From 4fd8873223a6d97e38293a95a32d08b2bc3316dd Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Wed, 5 Aug 2015 15:38:32 -0400 Subject: [PATCH] version 1.3.0 documentation --- analyzers/archive-analyzer.html | 26 +- analyzers/assembly-analyzer.html | 26 +- analyzers/autoconf-analyzer.html | 297 ++ analyzers/central-analyzer.html | 26 +- analyzers/index.html | 30 +- analyzers/jar-analyzer.html | 26 +- analyzers/nexus-analyzer.html | 26 +- analyzers/nuspec-analyzer.html | 26 +- analyzers/openssl-analyzer.html | 297 ++ analyzers/python-analyzer.html | 79 +- current.txt | 2 +- data/database.html | 12 +- data/index.html | 12 +- data/mirrornvd.html | 12 +- data/proxy.html | 12 +- .../apidocs/allclasses-frame.html | 9 +- .../apidocs/allclasses-noframe.html | 9 +- .../apidocs/constant-values.html | 18 +- .../apidocs/deprecated-list.html | 18 +- dependency-check-ant/apidocs/help-doc.html | 22 +- dependency-check-ant/apidocs/index-all.html | 163 +- dependency-check-ant/apidocs/index.html | 11 +- .../ant/logging/AntLoggerAdapter.html | 785 +++++ .../ant/logging/AntLoggerFactory.html | 278 ++ .../logging/class-use/AntLoggerAdapter.html | 117 + .../logging/class-use/AntLoggerFactory.html | 117 + .../ant/logging/package-frame.html | 21 + .../ant/logging/package-summary.html | 152 + .../ant/logging/package-tree.html | 135 + .../ant/logging/package-use.html | 117 + .../DependencyCheckTask.ReportFormats.html | 14 +- .../taskdefs/DependencyCheckTask.html | 126 +- .../DependencyCheckTask.ReportFormats.html | 31 +- .../class-use/DependencyCheckTask.html | 14 +- .../taskdefs/package-frame.html | 6 +- .../taskdefs/package-summary.html | 26 +- .../taskdefs/package-tree.html | 26 +- .../dependencycheck/taskdefs/package-use.html | 31 +- .../org/slf4j/impl/StaticLoggerBinder.html | 334 ++ .../impl/class-use/StaticLoggerBinder.html | 161 + .../apidocs/org/slf4j/impl/package-frame.html | 20 + .../org/slf4j/impl/package-summary.html | 147 + .../apidocs/org/slf4j/impl/package-tree.html | 130 + .../apidocs/org/slf4j/impl/package-use.html | 155 + .../apidocs/overview-frame.html | 23 + .../apidocs/overview-summary.html | 145 + .../apidocs/overview-tree.html | 25 +- dependency-check-ant/apidocs/package-list | 2 + .../apidocs/serialized-form.html | 144 + dependency-check-ant/checkstyle.html | 52 +- dependency-check-ant/checkstyle.rss | 106 +- .../cobertura/frame-packages.html | 6 + ...org.owasp.dependencycheck.ant.logging.html | 26 + .../frame-sourcefiles-org.slf4j.impl.html | 23 + .../cobertura/frame-sourcefiles.html | 9 + ...org.owasp.dependencycheck.ant.logging.html | 44 + ...ry-org.owasp.dependencycheck.taskdefs.html | 8 +- .../frame-summary-org.slf4j.impl.html | 42 + .../cobertura/frame-summary.html | 8 +- ...ncycheck.ant.logging.AntLoggerAdapter.html | 467 +++ ...ncycheck.ant.logging.AntLoggerFactory.html | 132 + ...ncycheck.taskdefs.DependencyCheckTask.html | 2796 ++++++++-------- .../org.slf4j.impl.StaticLoggerBinder.html | 217 ++ dependency-check-ant/configuration.html | 43 +- dependency-check-ant/cpd.html | 10 +- .../dependency-updates-report.html | 1054 +++++- dependency-check-ant/findbugs.html | 14 +- dependency-check-ant/index.html | 14 +- dependency-check-ant/issue-tracking.html | 10 +- dependency-check-ant/license.html | 10 +- dependency-check-ant/mail-lists.html | 10 +- .../plugin-updates-report.html | 89 +- dependency-check-ant/pmd.html | 10 +- dependency-check-ant/project-info.html | 10 +- dependency-check-ant/project-reports.html | 10 +- dependency-check-ant/project-summary.html | 12 +- dependency-check-ant/source-repository.html | 10 +- dependency-check-ant/surefire-report.html | 24 +- dependency-check-ant/taglist.html | 22 +- dependency-check-ant/team-list.html | 17 +- dependency-check-ant/usage.html | 12 +- dependency-check-ant/xref-test/index.html | 2 +- .../taskdefs/DependencyCheckTaskTest.html | 191 +- .../taskdefs/package-frame.html | 2 +- .../taskdefs/package-summary.html | 2 +- .../xref-test/overview-frame.html | 2 +- .../xref-test/overview-summary.html | 4 +- .../xref/allclasses-frame.html | 9 + dependency-check-ant/xref/index.html | 2 +- .../ant/logging/AntLoggerAdapter.html | 284 ++ .../ant/logging/AntLoggerFactory.html | 69 + .../ant/logging/package-frame.html | 27 + .../ant/logging/package-summary.html | 74 + .../taskdefs/DependencyCheckTask.html | 2289 +++++++------ .../taskdefs/package-frame.html | 2 +- .../taskdefs/package-summary.html | 2 +- .../org/slf4j/impl/StaticLoggerBinder.html | 116 + .../xref/org/slf4j/impl/package-frame.html | 24 + .../xref/org/slf4j/impl/package-summary.html | 69 + dependency-check-ant/xref/overview-frame.html | 8 +- .../xref/overview-summary.html | 14 +- .../apidocs/allclasses-frame.html | 6 +- .../apidocs/allclasses-noframe.html | 6 +- .../apidocs/constant-values.html | 108 +- .../apidocs/deprecated-list.html | 12 +- dependency-check-cli/apidocs/help-doc.html | 10 +- dependency-check-cli/apidocs/index-all.html | 80 +- dependency-check-cli/apidocs/index.html | 4 +- .../org/owasp/dependencycheck/App.html | 34 +- .../dependencycheck/CliParser.ARGUMENT.html | 192 +- .../org/owasp/dependencycheck/CliParser.html | 160 +- .../owasp/dependencycheck/class-use/App.html | 10 +- .../class-use/CliParser.ARGUMENT.html | 10 +- .../dependencycheck/class-use/CliParser.html | 10 +- .../owasp/dependencycheck/package-frame.html | 6 +- .../dependencycheck/package-summary.html | 10 +- .../owasp/dependencycheck/package-tree.html | 10 +- .../owasp/dependencycheck/package-use.html | 10 +- .../apidocs/overview-tree.html | 10 +- dependency-check-cli/arguments.html | 172 +- dependency-check-cli/checkstyle.html | 35 +- dependency-check-cli/checkstyle.rss | 124 +- ...sourcefiles-org.owasp.dependencycheck.html | 4 +- .../cobertura/frame-sourcefiles.html | 4 +- ...ame-summary-org.owasp.dependencycheck.html | 10 +- .../cobertura/frame-summary.html | 6 +- .../org.owasp.dependencycheck.App.html | 826 +++-- .../org.owasp.dependencycheck.CliParser.html | 2963 +++++++++-------- ...endencycheck.InvalidScanPathException.html | 2 +- dependency-check-cli/cpd.html | 268 ++ .../dependency-updates-report.html | 1102 +++++- dependency-check-cli/findbugs.html | 45 +- dependency-check-cli/index.html | 14 +- dependency-check-cli/issue-tracking.html | 12 +- dependency-check-cli/license.html | 12 +- dependency-check-cli/mail-lists.html | 12 +- .../plugin-updates-report.html | 102 +- dependency-check-cli/pmd.html | 70 +- dependency-check-cli/project-info.html | 12 +- dependency-check-cli/project-reports.html | 30 +- dependency-check-cli/project-summary.html | 14 +- dependency-check-cli/source-repository.html | 12 +- dependency-check-cli/surefire-report.html | 63 +- dependency-check-cli/taglist.html | 23 +- dependency-check-cli/team-list.html | 19 +- .../xref-test/allclasses-frame.html | 3 + dependency-check-cli/xref-test/index.html | 2 +- .../org/owasp/dependencycheck/AppTest.html | 86 + .../owasp/dependencycheck/package-frame.html | 5 +- .../dependencycheck/package-summary.html | 7 +- .../xref-test/overview-frame.html | 2 +- .../xref-test/overview-summary.html | 4 +- dependency-check-cli/xref/index.html | 2 +- .../xref/org/owasp/dependencycheck/App.html | 748 +++-- .../org/owasp/dependencycheck/CliParser.html | 2058 ++++++------ .../owasp/dependencycheck/package-frame.html | 2 +- .../dependencycheck/package-summary.html | 2 +- dependency-check-cli/xref/overview-frame.html | 2 +- .../xref/overview-summary.html | 4 +- .../apidocs/allclasses-frame.html | 32 +- .../apidocs/allclasses-noframe.html | 32 +- .../apidocs/constant-values.html | 215 +- .../apidocs/deprecated-list.html | 8 +- dependency-check-core/apidocs/help-doc.html | 8 +- dependency-check-core/apidocs/index-all.html | 754 +++-- dependency-check-core/apidocs/index.html | 4 +- .../org/owasp/dependencycheck/Engine.html | 79 +- .../agent/DependencyCheckScanAgent.html | 8 +- .../class-use/DependencyCheckScanAgent.html | 8 +- .../dependencycheck/agent/package-frame.html | 6 +- .../agent/package-summary.html | 8 +- .../dependencycheck/agent/package-tree.html | 8 +- .../dependencycheck/agent/package-use.html | 8 +- .../analyzer/AbstractAnalyzer.html | 8 +- .../analyzer/AbstractFileTypeAnalyzer.html | 100 +- .../analyzer/AbstractSuppressionAnalyzer.html | 8 +- .../analyzer/AnalysisPhase.html | 8 +- .../dependencycheck/analyzer/Analyzer.html | 10 +- .../analyzer/AnalyzerService.html | 8 +- .../analyzer/ArchiveAnalyzer.html | 52 +- .../analyzer/AssemblyAnalyzer.html | 55 +- .../analyzer/AutoconfAnalyzer.html | 408 +++ .../analyzer/CMakeAnalyzer.html | 414 +++ .../dependencycheck/analyzer/CPEAnalyzer.html | 12 +- .../analyzer/CentralAnalyzer.html | 52 +- .../analyzer/CpeSuppressionAnalyzer.html | 8 +- .../analyzer/DependencyBundlingAnalyzer.html | 8 +- .../analyzer/FalsePositiveAnalyzer.html | 8 +- .../analyzer/FileNameAnalyzer.html | 8 +- .../analyzer/FileTypeAnalyzer.html | 39 +- .../analyzer/HintAnalyzer.html | 8 +- .../JarAnalyzer.ClassNameInformation.html | 12 +- .../dependencycheck/analyzer/JarAnalyzer.html | 36 +- .../analyzer/NexusAnalyzer.html | 40 +- .../analyzer/NuspecAnalyzer.html | 36 +- .../analyzer/NvdCveAnalyzer.html | 12 +- .../analyzer/OpenSSLAnalyzer.html | 407 +++ .../analyzer/PythonDistributionAnalyzer.html | 44 +- .../analyzer/PythonPackageAnalyzer.html | 36 +- .../VulnerabilitySuppressionAnalyzer.html | 8 +- .../analyzer/class-use/AbstractAnalyzer.html | 39 +- .../class-use/AbstractFileTypeAnalyzer.html | 39 +- .../AbstractSuppressionAnalyzer.html | 8 +- .../analyzer/class-use/AnalysisPhase.html | 36 +- .../analyzer/class-use/Analyzer.html | 41 +- .../analyzer/class-use/AnalyzerService.html | 8 +- .../analyzer/class-use/ArchiveAnalyzer.html | 8 +- .../analyzer/class-use/AssemblyAnalyzer.html | 8 +- .../analyzer/class-use/AutoconfAnalyzer.html | 117 + .../analyzer/class-use/CMakeAnalyzer.html | 117 + .../analyzer/class-use/CPEAnalyzer.html | 8 +- .../analyzer/class-use/CentralAnalyzer.html | 8 +- .../class-use/CpeSuppressionAnalyzer.html | 8 +- .../class-use/DependencyBundlingAnalyzer.html | 8 +- .../class-use/FalsePositiveAnalyzer.html | 8 +- .../analyzer/class-use/FileNameAnalyzer.html | 8 +- .../analyzer/class-use/FileTypeAnalyzer.html | 39 +- .../analyzer/class-use/HintAnalyzer.html | 8 +- .../JarAnalyzer.ClassNameInformation.html | 8 +- .../analyzer/class-use/JarAnalyzer.html | 8 +- .../analyzer/class-use/NexusAnalyzer.html | 8 +- .../analyzer/class-use/NuspecAnalyzer.html | 8 +- .../analyzer/class-use/NvdCveAnalyzer.html | 8 +- .../analyzer/class-use/OpenSSLAnalyzer.html | 117 + .../class-use/PythonDistributionAnalyzer.html | 8 +- .../class-use/PythonPackageAnalyzer.html | 8 +- .../VulnerabilitySuppressionAnalyzer.html | 8 +- .../analyzer/exception/AnalysisException.html | 8 +- .../exception/ArchiveExtractionException.html | 8 +- .../class-use/AnalysisException.html | 36 +- .../class-use/ArchiveExtractionException.html | 8 +- .../analyzer/exception/package-frame.html | 6 +- .../analyzer/exception/package-summary.html | 8 +- .../analyzer/exception/package-tree.html | 8 +- .../analyzer/exception/package-use.html | 8 +- .../analyzer/package-frame.html | 10 +- .../analyzer/package-summary.html | 41 +- .../analyzer/package-tree.html | 19 +- .../dependencycheck/analyzer/package-use.html | 8 +- .../dependencycheck/class-use/Engine.html | 36 +- .../data/central/CentralSearch.html | 8 +- .../data/central/class-use/CentralSearch.html | 8 +- .../data/central/package-frame.html | 6 +- .../data/central/package-summary.html | 8 +- .../data/central/package-tree.html | 8 +- .../data/central/package-use.html | 8 +- .../data/cpe/CpeMemoryIndex.html | 8 +- .../dependencycheck/data/cpe/Fields.html | 8 +- .../dependencycheck/data/cpe/IndexEntry.html | 8 +- .../data/cpe/IndexException.html | 8 +- .../data/cpe/class-use/CpeMemoryIndex.html | 8 +- .../data/cpe/class-use/Fields.html | 8 +- .../data/cpe/class-use/IndexEntry.html | 8 +- .../data/cpe/class-use/IndexException.html | 8 +- .../data/cpe/package-frame.html | 6 +- .../data/cpe/package-summary.html | 8 +- .../data/cpe/package-tree.html | 8 +- .../dependencycheck/data/cpe/package-use.html | 8 +- .../owasp/dependencycheck/data/cwe/CweDB.html | 8 +- .../dependencycheck/data/cwe/CweHandler.html | 8 +- .../data/cwe/class-use/CweDB.html | 8 +- .../data/cwe/class-use/CweHandler.html | 8 +- .../data/cwe/package-frame.html | 6 +- .../data/cwe/package-summary.html | 8 +- .../data/cwe/package-tree.html | 8 +- .../dependencycheck/data/cwe/package-use.html | 8 +- .../data/lucene/AbstractTokenizingFilter.html | 8 +- .../data/lucene/AlphaNumericTokenizer.html | 8 +- .../data/lucene/DependencySimilarity.html | 8 +- .../data/lucene/FieldAnalyzer.html | 8 +- .../data/lucene/LuceneUtils.html | 8 +- .../data/lucene/SearchFieldAnalyzer.html | 8 +- .../lucene/TokenPairConcatenatingFilter.html | 8 +- .../data/lucene/UrlTokenizingFilter.html | 8 +- .../class-use/AbstractTokenizingFilter.html | 8 +- .../class-use/AlphaNumericTokenizer.html | 8 +- .../class-use/DependencySimilarity.html | 8 +- .../data/lucene/class-use/FieldAnalyzer.html | 8 +- .../data/lucene/class-use/LuceneUtils.html | 8 +- .../lucene/class-use/SearchFieldAnalyzer.html | 8 +- .../TokenPairConcatenatingFilter.html | 8 +- .../lucene/class-use/UrlTokenizingFilter.html | 8 +- .../data/lucene/package-frame.html | 6 +- .../data/lucene/package-summary.html | 8 +- .../data/lucene/package-tree.html | 8 +- .../data/lucene/package-use.html | 8 +- .../data/nexus/MavenArtifact.html | 8 +- .../data/nexus/NexusSearch.html | 8 +- .../data/nexus/class-use/MavenArtifact.html | 8 +- .../data/nexus/class-use/NexusSearch.html | 8 +- .../data/nexus/package-frame.html | 6 +- .../data/nexus/package-summary.html | 8 +- .../data/nexus/package-tree.html | 8 +- .../data/nexus/package-use.html | 8 +- .../data/nuget/NugetPackage.html | 8 +- .../data/nuget/NuspecParseException.html | 8 +- .../data/nuget/NuspecParser.html | 8 +- .../data/nuget/XPathNuspecParser.html | 8 +- .../data/nuget/class-use/NugetPackage.html | 8 +- .../nuget/class-use/NuspecParseException.html | 8 +- .../data/nuget/class-use/NuspecParser.html | 8 +- .../nuget/class-use/XPathNuspecParser.html | 8 +- .../data/nuget/package-frame.html | 6 +- .../data/nuget/package-summary.html | 8 +- .../data/nuget/package-tree.html | 8 +- .../data/nuget/package-use.html | 8 +- .../data/nvdcve/ConnectionFactory.html | 40 +- .../dependencycheck/data/nvdcve/CveDB.html | 53 +- .../data/nvdcve/DatabaseException.html | 8 +- .../data/nvdcve/DatabaseProperties.html | 79 +- .../data/nvdcve/DriverLoadException.html | 8 +- .../data/nvdcve/DriverLoader.html | 8 +- .../nvdcve/class-use/ConnectionFactory.html | 8 +- .../data/nvdcve/class-use/CveDB.html | 77 +- .../nvdcve/class-use/DatabaseException.html | 20 +- .../nvdcve/class-use/DatabaseProperties.html | 21 +- .../nvdcve/class-use/DriverLoadException.html | 8 +- .../data/nvdcve/class-use/DriverLoader.html | 8 +- .../data/nvdcve/package-frame.html | 6 +- .../data/nvdcve/package-summary.html | 8 +- .../data/nvdcve/package-tree.html | 8 +- .../data/nvdcve/package-use.html | 54 +- .../data/update/BaseUpdater.html | 312 ++ .../data/update/CachedWebDataSource.html | 18 +- .../data/update/CpeUpdater.html | 292 ++ .../data/update/EngineVersionCheck.html | 20 +- .../data/update/NvdCveUpdater.html | 127 +- .../data/update/UpdateService.html | 12 +- .../data/update/class-use/BaseUpdater.html | 169 + .../update/class-use/CachedWebDataSource.html | 18 +- .../data/update/class-use/CpeUpdater.html | 117 + .../update/class-use/EngineVersionCheck.html | 8 +- .../data/update/class-use/NvdCveUpdater.html | 8 +- .../data/update/class-use/UpdateService.html | 8 +- .../data/update/cpe/CPEHandler.Element.html | 717 ++++ .../data/update/cpe/CPEHandler.html | 391 +++ .../dependencycheck/data/update/cpe/Cpe.html | 378 +++ .../cpe/class-use/CPEHandler.Element.html | 117 + .../data/update/cpe/class-use/CPEHandler.html | 117 + .../data/update/cpe/class-use/Cpe.html | 163 + .../data/update/cpe/package-frame.html | 21 + .../data/update/cpe/package-summary.html | 155 + .../data/update/cpe/package-tree.html | 136 + .../data/update/cpe/package-use.html | 154 + .../exception/InvalidDataException.html | 8 +- .../update/exception/UpdateException.html | 8 +- .../class-use/InvalidDataException.html | 54 +- .../exception/class-use/UpdateException.html | 74 +- .../data/update/exception/package-frame.html | 6 +- .../update/exception/package-summary.html | 16 +- .../data/update/exception/package-tree.html | 16 +- .../data/update/exception/package-use.html | 43 +- .../data/update/nvd/DownloadTask.html | 438 +++ .../update/nvd/NvdCve12Handler.Element.html | 479 +++ .../data/update/nvd/NvdCve12Handler.html | 356 ++ .../update/nvd/NvdCve20Handler.Element.html | 819 +++++ .../data/update/nvd/NvdCve20Handler.html | 430 +++ .../data/update/nvd/NvdCveInfo.html | 418 +++ .../data/update/nvd/ProcessTask.html | 352 ++ .../data/update/nvd/UpdateableNvdCve.html | 507 +++ .../update/nvd/class-use/DownloadTask.html | 161 + .../class-use/NvdCve12Handler.Element.html | 117 + .../update/nvd/class-use/NvdCve12Handler.html | 117 + .../class-use/NvdCve20Handler.Element.html | 117 + .../update/nvd/class-use/NvdCve20Handler.html | 117 + .../data/update/nvd/class-use/NvdCveInfo.html | 253 ++ .../update/nvd/class-use/ProcessTask.html | 174 + .../nvd/class-use/UpdateableNvdCve.html | 178 + .../data/update/nvd/package-frame.html | 27 + .../data/update/nvd/package-summary.html | 188 ++ .../data/update/nvd/package-tree.html | 141 + .../data/update/nvd/package-use.html | 212 ++ .../data/update/package-frame.html | 11 +- .../data/update/package-summary.html | 42 +- .../data/update/package-tree.html | 22 +- .../data/update/package-use.html | 67 +- .../dependency/Confidence.html | 8 +- .../dependency/Dependency.html | 91 +- .../dependencycheck/dependency/Evidence.html | 8 +- .../dependency/EvidenceCollection.html | 28 +- .../dependency/Identifier.html | 8 +- .../dependencycheck/dependency/Reference.html | 8 +- .../dependency/Vulnerability.html | 8 +- .../dependency/VulnerabilityComparator.html | 8 +- .../dependency/VulnerableSoftware.html | 42 +- .../dependency/class-use/Confidence.html | 8 +- .../dependency/class-use/Dependency.html | 38 +- .../dependency/class-use/Evidence.html | 8 +- .../class-use/EvidenceCollection.html | 8 +- .../dependency/class-use/Identifier.html | 8 +- .../dependency/class-use/Reference.html | 8 +- .../dependency/class-use/Vulnerability.html | 8 +- .../class-use/VulnerabilityComparator.html | 8 +- .../class-use/VulnerableSoftware.html | 26 +- .../dependency/package-frame.html | 6 +- .../dependency/package-summary.html | 12 +- .../dependency/package-tree.html | 12 +- .../dependency/package-use.html | 20 +- .../exception/NoDataException.html | 8 +- .../exception/ScanAgentException.html | 8 +- .../exception/class-use/NoDataException.html | 8 +- .../class-use/ScanAgentException.html | 8 +- .../exception/package-frame.html | 6 +- .../exception/package-summary.html | 8 +- .../exception/package-tree.html | 8 +- .../exception/package-use.html | 8 +- .../owasp/dependencycheck/package-frame.html | 6 +- .../dependencycheck/package-summary.html | 8 +- .../owasp/dependencycheck/package-tree.html | 10 +- .../owasp/dependencycheck/package-use.html | 8 +- .../dependencycheck/reporting/EscapeTool.html | 8 +- .../reporting/ReportGenerator.Format.html | 8 +- .../reporting/ReportGenerator.html | 8 +- .../reporting/VelocityLoggerRedirect.html | 10 +- .../reporting/class-use/EscapeTool.html | 8 +- .../class-use/ReportGenerator.Format.html | 8 +- .../reporting/class-use/ReportGenerator.html | 8 +- .../class-use/VelocityLoggerRedirect.html | 8 +- .../reporting/package-frame.html | 6 +- .../reporting/package-summary.html | 10 +- .../reporting/package-tree.html | 8 +- .../reporting/package-use.html | 8 +- .../suppression/PropertyType.html | 8 +- .../suppression/SuppressionErrorHandler.html | 8 +- .../suppression/SuppressionHandler.html | 8 +- .../SuppressionParseException.html | 8 +- .../suppression/SuppressionParser.html | 8 +- .../suppression/SuppressionRule.html | 8 +- .../suppression/class-use/PropertyType.html | 8 +- .../class-use/SuppressionErrorHandler.html | 8 +- .../class-use/SuppressionHandler.html | 8 +- .../class-use/SuppressionParseException.html | 8 +- .../class-use/SuppressionParser.html | 8 +- .../class-use/SuppressionRule.html | 8 +- .../suppression/package-frame.html | 6 +- .../suppression/package-summary.html | 8 +- .../suppression/package-tree.html | 8 +- .../suppression/package-use.html | 8 +- .../owasp/dependencycheck/utils/DBUtils.html | 8 +- .../owasp/dependencycheck/utils/DateUtil.html | 8 +- .../utils/DependencyVersion.html | 8 +- .../utils/DependencyVersionUtil.html | 8 +- .../dependencycheck/utils/ExtractionUtil.html | 12 +- .../utils/FileFilterBuilder.html | 364 ++ .../owasp/dependencycheck/utils/Filter.html | 12 +- .../utils/NonClosingStream.html | 8 +- .../org/owasp/dependencycheck/utils/Pair.html | 8 +- .../dependencycheck/utils/UrlStringUtils.html | 8 +- .../utils/class-use/DBUtils.html | 8 +- .../utils/class-use/DateUtil.html | 8 +- .../utils/class-use/DependencyVersion.html | 8 +- .../class-use/DependencyVersionUtil.html | 8 +- .../utils/class-use/ExtractionUtil.html | 8 +- .../utils/class-use/FileFilterBuilder.html | 185 + .../utils/class-use/Filter.html | 8 +- .../utils/class-use/NonClosingStream.html | 8 +- .../dependencycheck/utils/class-use/Pair.html | 8 +- .../utils/class-use/UrlStringUtils.html | 8 +- .../dependencycheck/utils/package-frame.html | 7 +- .../utils/package-summary.html | 22 +- .../dependencycheck/utils/package-tree.html | 9 +- .../dependencycheck/utils/package-use.html | 15 +- .../dependencycheck/xml/pom/License.html | 8 +- .../owasp/dependencycheck/xml/pom/Model.html | 8 +- .../dependencycheck/xml/pom/PomHandler.html | 8 +- .../xml/pom/PomParseException.html | 8 +- .../dependencycheck/xml/pom/PomParser.html | 8 +- .../dependencycheck/xml/pom/PomUtils.html | 14 +- .../xml/pom/class-use/License.html | 8 +- .../xml/pom/class-use/Model.html | 8 +- .../xml/pom/class-use/PomHandler.html | 8 +- .../xml/pom/class-use/PomParseException.html | 8 +- .../xml/pom/class-use/PomParser.html | 8 +- .../xml/pom/class-use/PomUtils.html | 8 +- .../xml/pom/package-frame.html | 6 +- .../xml/pom/package-summary.html | 8 +- .../dependencycheck/xml/pom/package-tree.html | 8 +- .../dependencycheck/xml/pom/package-use.html | 8 +- .../apidocs/overview-frame.html | 10 +- .../apidocs/overview-summary.html | 30 +- .../apidocs/overview-tree.html | 53 +- dependency-check-core/apidocs/package-list | 4 +- .../apidocs/serialized-form.html | 19 +- dependency-check-core/checkstyle.html | 114 +- dependency-check-core/checkstyle.rss | 514 ++- .../cobertura/frame-packages.html | 8 +- ...es-org.owasp.dependencycheck.analyzer.html | 26 +- ...rg.owasp.dependencycheck.data.central.html | 2 +- ...es-org.owasp.dependencycheck.data.cpe.html | 2 +- ...org.owasp.dependencycheck.data.nvdcve.html | 8 +- ...owasp.dependencycheck.data.update.cpe.html | 26 + ...org.owasp.dependencycheck.data.update.html | 13 +- ...owasp.dependencycheck.data.update.nvd.html | 38 + ...-org.owasp.dependencycheck.dependency.html | 4 +- ...sourcefiles-org.owasp.dependencycheck.html | 2 +- ...files-org.owasp.dependencycheck.utils.html | 3 + ...les-org.owasp.dependencycheck.xml.pom.html | 2 +- .../cobertura/frame-sourcefiles.html | 78 +- ...mmary-org.owasp.dependencycheck.agent.html | 6 +- ...sp.dependencycheck.analyzer.exception.html | 2 +- ...ry-org.owasp.dependencycheck.analyzer.html | 40 +- ...rg.owasp.dependencycheck.data.central.html | 6 +- ...ry-org.owasp.dependencycheck.data.cpe.html | 6 +- ...ry-org.owasp.dependencycheck.data.cwe.html | 2 +- ...org.owasp.dependencycheck.data.lucene.html | 2 +- ...-org.owasp.dependencycheck.data.nexus.html | 6 +- ...-org.owasp.dependencycheck.data.nuget.html | 2 +- ...org.owasp.dependencycheck.data.nvdcve.html | 12 +- ...owasp.dependencycheck.data.update.cpe.html | 45 + ...dependencycheck.data.update.exception.html | 2 +- ...org.owasp.dependencycheck.data.update.html | 20 +- ...owasp.dependencycheck.data.update.nvd.html | 54 + ...-org.owasp.dependencycheck.dependency.html | 22 +- ...y-org.owasp.dependencycheck.exception.html | 2 +- ...ame-summary-org.owasp.dependencycheck.html | 32 +- ...y-org.owasp.dependencycheck.reporting.html | 8 +- ...org.owasp.dependencycheck.suppression.html | 2 +- ...mmary-org.owasp.dependencycheck.utils.html | 10 +- ...ary-org.owasp.dependencycheck.xml.pom.html | 6 +- .../cobertura/frame-summary.html | 32 +- .../org.owasp.dependencycheck.Engine.html | 1093 +++--- ...ycheck.agent.DependencyCheckScanAgent.html | 61 +- ...ndencycheck.analyzer.AbstractAnalyzer.html | 8 +- ...eck.analyzer.AbstractFileTypeAnalyzer.html | 474 ++- ....analyzer.AbstractSuppressionAnalyzer.html | 163 +- ...ependencycheck.analyzer.AnalysisPhase.html | 22 +- ...asp.dependencycheck.analyzer.Analyzer.html | 2 +- ...endencycheck.analyzer.AnalyzerService.html | 10 +- ...endencycheck.analyzer.ArchiveAnalyzer.html | 1157 +++---- ...ndencycheck.analyzer.AssemblyAnalyzer.html | 874 ++--- ...ndencycheck.analyzer.AutoconfAnalyzer.html | 515 +++ ...ependencycheck.analyzer.CMakeAnalyzer.html | 393 +++ ....dependencycheck.analyzer.CPEAnalyzer.html | 1516 ++++----- ...endencycheck.analyzer.CentralAnalyzer.html | 490 +-- ...check.analyzer.CpeSuppressionAnalyzer.html | 20 +- ...k.analyzer.DependencyBundlingAnalyzer.html | 555 +-- ...ycheck.analyzer.FalsePositiveAnalyzer.html | 1217 +++---- ...ndencycheck.analyzer.FileNameAnalyzer.html | 38 +- ...ndencycheck.analyzer.FileTypeAnalyzer.html | 40 +- ...dependencycheck.analyzer.HintAnalyzer.html | 129 +- ....dependencycheck.analyzer.JarAnalyzer.html | 2850 ++++++++-------- ...ependencycheck.analyzer.NexusAnalyzer.html | 546 +-- ...pendencycheck.analyzer.NuspecAnalyzer.html | 352 +- ...pendencycheck.analyzer.NvdCveAnalyzer.html | 50 +- ...endencycheck.analyzer.OpenSSLAnalyzer.html | 338 ++ ...k.analyzer.PythonDistributionAnalyzer.html | 946 +++--- ...ycheck.analyzer.PythonPackageAnalyzer.html | 801 ++--- ...yzer.VulnerabilitySuppressionAnalyzer.html | 20 +- ....analyzer.exception.AnalysisException.html | 6 +- ....exception.ArchiveExtractionException.html | 2 +- ...dencycheck.data.central.CentralSearch.html | 315 +- ...pendencycheck.data.cpe.CpeMemoryIndex.html | 200 +- ...owasp.dependencycheck.data.cpe.Fields.html | 2 +- ...p.dependencycheck.data.cpe.IndexEntry.html | 52 +- ...pendencycheck.data.cpe.IndexException.html | 2 +- ....owasp.dependencycheck.data.cwe.CweDB.html | 186 +- ...p.dependencycheck.data.cwe.CweHandler.html | 2 +- ....data.lucene.AbstractTokenizingFilter.html | 26 +- ...eck.data.lucene.AlphaNumericTokenizer.html | 8 +- ...heck.data.lucene.DependencySimilarity.html | 2 +- ...ndencycheck.data.lucene.FieldAnalyzer.html | 20 +- ...pendencycheck.data.lucene.LuceneUtils.html | 34 +- ...check.data.lucene.SearchFieldAnalyzer.html | 32 +- ...a.lucene.TokenPairConcatenatingFilter.html | 54 +- ...check.data.lucene.UrlTokenizingFilter.html | 50 +- ...endencycheck.data.nexus.MavenArtifact.html | 46 +- ...ependencycheck.data.nexus.NexusSearch.html | 322 +- ...pendencycheck.data.nuget.NugetPackage.html | 42 +- ...check.data.nuget.NuspecParseException.html | 10 +- ...pendencycheck.data.nuget.NuspecParser.html | 2 +- ...ncycheck.data.nuget.XPathNuspecParser.html | 36 +- ...cycheck.data.nvdcve.ConnectionFactory.html | 656 ++-- ....data.nvdcve.CorruptDatabaseException.html | 2 +- ...asp.dependencycheck.data.nvdcve.CveDB.html | 1620 ++++----- ...cycheck.data.nvdcve.DatabaseException.html | 2 +- ...ycheck.data.nvdcve.DatabaseProperties.html | 348 +- ...check.data.nvdcve.DriverLoadException.html | 6 +- ...endencycheck.data.nvdcve.DriverLoader.html | 298 +- ...ependencycheck.data.nvdcve.DriverShim.html | 496 +-- ...pendencycheck.data.update.BaseUpdater.html | 176 + ...check.data.update.CachedWebDataSource.html | 2 +- ...ependencycheck.data.update.CpeUpdater.html | 345 ++ ...ycheck.data.update.EngineVersionCheck.html | 234 +- ...ndencycheck.data.update.NvdCveUpdater.html | 419 ++- ...ndencycheck.data.update.UpdateService.html | 2 +- ...dencycheck.data.update.cpe.CPEHandler.html | 706 ++++ ...p.dependencycheck.data.update.cpe.Cpe.html | 256 ++ ...update.exception.InvalidDataException.html | 2 +- ...data.update.exception.UpdateException.html | 2 +- ...ncycheck.data.update.nvd.DownloadTask.html | 529 +++ ...check.data.update.nvd.NvdCve12Handler.html | 454 +++ ...check.data.update.nvd.NvdCve20Handler.html | 872 +++++ ...dencycheck.data.update.nvd.NvdCveInfo.html | 281 ++ ...encycheck.data.update.nvd.ProcessTask.html | 339 ++ ...heck.data.update.nvd.UpdateableNvdCve.html | 362 ++ ...dependencycheck.dependency.Confidence.html | 12 +- ...dependencycheck.dependency.Dependency.html | 1805 +++++----- ...p.dependencycheck.dependency.Evidence.html | 818 +++-- ...cycheck.dependency.EvidenceCollection.html | 227 +- ...dependencycheck.dependency.Identifier.html | 34 +- ....dependencycheck.dependency.Reference.html | 28 +- ...endencycheck.dependency.Vulnerability.html | 98 +- ...ck.dependency.VulnerabilityComparator.html | 6 +- ...cycheck.dependency.VulnerableSoftware.html | 712 ++-- ...ndencycheck.exception.NoDataException.html | 2 +- ...ncycheck.exception.ScanAgentException.html | 2 +- ....dependencycheck.reporting.EscapeTool.html | 16 +- ...ndencycheck.reporting.ReportGenerator.html | 191 +- ...heck.reporting.VelocityLoggerRedirect.html | 179 +- ...endencycheck.suppression.PropertyType.html | 58 +- ...k.suppression.SuppressionErrorHandler.html | 12 +- ...ycheck.suppression.SuppressionHandler.html | 90 +- ...suppression.SuppressionParseException.html | 10 +- ...cycheck.suppression.SuppressionParser.html | 250 +- ...encycheck.suppression.SuppressionRule.html | 238 +- ...g.owasp.dependencycheck.utils.DBUtils.html | 32 +- ....owasp.dependencycheck.utils.DateUtil.html | 6 +- ...pendencycheck.utils.DependencyVersion.html | 164 +- ...encycheck.utils.DependencyVersionUtil.html | 52 +- ....dependencycheck.utils.ExtractionUtil.html | 597 ++-- ...pendencycheck.utils.FileFilterBuilder.html | 275 ++ ...rg.owasp.dependencycheck.utils.Filter.html | 46 +- ...ependencycheck.utils.NonClosingStream.html | 2 +- .../org.owasp.dependencycheck.utils.Pair.html | 26 +- ....dependencycheck.utils.UrlStringUtils.html | 42 +- ...owasp.dependencycheck.xml.pom.License.html | 22 +- ...g.owasp.dependencycheck.xml.pom.Model.html | 124 +- ...sp.dependencycheck.xml.pom.PomHandler.html | 72 +- ...ndencycheck.xml.pom.PomParseException.html | 2 +- ...asp.dependencycheck.xml.pom.PomParser.html | 224 +- ...wasp.dependencycheck.xml.pom.PomUtils.html | 166 +- dependency-check-core/cpd.html | 111 +- .../dependency-updates-report.html | 1035 ++++-- dependency-check-core/failsafe-report.html | 200 +- dependency-check-core/findbugs.html | 86 +- dependency-check-core/index.html | 10 +- dependency-check-core/issue-tracking.html | 10 +- dependency-check-core/license.html | 10 +- dependency-check-core/mail-lists.html | 10 +- .../plugin-updates-report.html | 97 +- dependency-check-core/pmd.html | 235 +- dependency-check-core/project-info.html | 10 +- dependency-check-core/project-reports.html | 26 +- dependency-check-core/project-summary.html | 12 +- dependency-check-core/source-repository.html | 10 +- dependency-check-core/surefire-report.html | 632 ++-- dependency-check-core/taglist.html | 74 +- dependency-check-core/team-list.html | 17 +- .../xref-test/allclasses-frame.html | 37 +- dependency-check-core/xref-test/index.html | 2 +- .../org/owasp/dependencycheck/BaseTest.html | 69 +- .../AbstractSuppressionAnalyzerTest.html | 183 +- .../ArchiveAnalyzerIntegrationTest.html | 495 ++- .../analyzer/AssemblyAnalyzerTest.html | 298 +- .../analyzer/AutoconfAnalyzerTest.html | 189 ++ .../analyzer/CMakeAnalyzerTest.html | 165 + .../analyzer/CPEAnalyzerIntegrationTest.html | 215 +- ...ndencyBundlingAnalyzerIntegrationTest.html | 118 + .../analyzer/HintAnalyzerTest.html | 7 +- .../analyzer/JarAnalyzerTest.html | 79 +- .../analyzer/NuspecAnalyzerTest.html | 61 +- .../analyzer/OpenSSLAnalyzerTest.html | 132 + .../PythonDistributionAnalyzerTest.html | 312 +- .../analyzer/PythonPackageAnalyzerTest.html | 187 +- .../analyzer/package-frame.html | 15 +- .../analyzer/package-summary.html | 21 +- .../data/central/CentralSearchTest.html | 113 +- .../data/central/package-frame.html | 2 +- .../data/central/package-summary.html | 2 +- .../data/cpe/package-frame.html | 2 +- .../data/cpe/package-summary.html | 2 +- .../data/cwe/package-frame.html | 2 +- .../data/cwe/package-summary.html | 2 +- .../data/lucene/package-frame.html | 2 +- .../data/lucene/package-summary.html | 2 +- .../data/nexus/NexusSearchTest.html | 119 +- .../data/nexus/package-frame.html | 2 +- .../data/nexus/package-summary.html | 2 +- .../data/nuget/package-frame.html | 2 +- .../data/nuget/package-summary.html | 2 +- .../data/nvdcve/BaseDBTestCase.html | 169 +- .../data/nvdcve/CveDBIntegrationTest.html | 241 +- .../DatabasePropertiesIntegrationTest.html | 190 +- .../data/nvdcve/package-frame.html | 2 +- .../data/nvdcve/package-summary.html | 2 +- .../data/update/BaseUpdaterTest.html | 113 + .../update/CpeUpdaterIntegrationTest.html | 56 + .../update/NvdCveUpdaterIntegrationTest.html | 93 +- .../data/update/nvd/DownloadTaskTest.html | 90 + .../data/update/nvd/NvdCveInfoTest.html | 104 + .../nvd/NvdCveUpdaterIntegrationTest.html | 82 + .../update/nvd/NvdCve_1_2_HandlerTest.html | 86 + .../update/nvd/NvdCve_2_0_HandlerTest.html | 92 + .../data/update/nvd/UpdateableNvdCveTest.html | 154 + .../data/update/nvd/package-frame.html | 39 + .../data/update/nvd/package-summary.html | 94 + .../data/update/package-frame.html | 20 +- .../data/update/package-summary.html | 32 +- .../dependency/DependencyTest.html | 471 ++- .../dependency/EvidenceTest.html | 153 +- .../dependency/package-frame.html | 2 +- .../dependency/package-summary.html | 2 +- .../owasp/dependencycheck/package-frame.html | 2 +- .../dependencycheck/package-summary.html | 2 +- .../ReportGeneratorIntegrationTest.html | 2 +- .../reporting/package-frame.html | 2 +- .../reporting/package-summary.html | 2 +- .../suppression/package-frame.html | 2 +- .../suppression/package-summary.html | 2 +- .../dependencycheck/utils/package-frame.html | 2 +- .../utils/package-summary.html | 2 +- .../xml/pom/package-frame.html | 2 +- .../xml/pom/package-summary.html | 2 +- .../xref-test/overview-frame.html | 7 +- .../xref-test/overview-summary.html | 11 +- .../xref/allclasses-frame.html | 44 +- dependency-check-core/xref/index.html | 2 +- .../org/owasp/dependencycheck/Engine.html | 958 +++--- .../agent/DependencyCheckScanAgent.html | 55 +- .../dependencycheck/agent/package-frame.html | 2 +- .../agent/package-summary.html | 2 +- .../analyzer/AbstractFileTypeAnalyzer.html | 422 ++- .../analyzer/AbstractSuppressionAnalyzer.html | 91 +- .../analyzer/ArchiveAnalyzer.html | 930 +++--- .../analyzer/AssemblyAnalyzer.html | 623 ++-- .../analyzer/AutoconfAnalyzer.html | 292 ++ .../analyzer/CMakeAnalyzer.html | 229 ++ .../dependencycheck/analyzer/CPEAnalyzer.html | 1030 +++--- .../analyzer/CentralAnalyzer.html | 409 ++- .../analyzer/DependencyBundlingAnalyzer.html | 502 +-- .../analyzer/FalsePositiveAnalyzer.html | 900 ++--- .../analyzer/FileTypeAnalyzer.html | 34 +- .../analyzer/HintAnalyzer.html | 97 +- .../dependencycheck/analyzer/JarAnalyzer.html | 2234 +++++++------ .../analyzer/NexusAnalyzer.html | 469 +-- .../analyzer/NuspecAnalyzer.html | 280 +- .../analyzer/OpenSSLAnalyzer.html | 188 ++ .../analyzer/PythonDistributionAnalyzer.html | 686 ++-- .../analyzer/PythonPackageAnalyzer.html | 570 ++-- .../analyzer/exception/package-frame.html | 2 +- .../analyzer/exception/package-summary.html | 2 +- .../analyzer/package-frame.html | 14 +- .../analyzer/package-summary.html | 22 +- .../data/central/CentralSearch.html | 282 +- .../data/central/package-frame.html | 2 +- .../data/central/package-summary.html | 2 +- .../data/cpe/CpeMemoryIndex.html | 56 +- .../data/cpe/package-frame.html | 2 +- .../data/cpe/package-summary.html | 2 +- .../owasp/dependencycheck/data/cwe/CweDB.html | 151 +- .../data/cwe/package-frame.html | 2 +- .../data/cwe/package-summary.html | 2 +- .../data/lucene/UrlTokenizingFilter.html | 14 +- .../data/lucene/package-frame.html | 2 +- .../data/lucene/package-summary.html | 2 +- .../data/nexus/NexusSearch.html | 287 +- .../data/nexus/package-frame.html | 2 +- .../data/nexus/package-summary.html | 2 +- .../data/nuget/package-frame.html | 2 +- .../data/nuget/package-summary.html | 2 +- .../data/nvdcve/ConnectionFactory.html | 516 +-- .../dependencycheck/data/nvdcve/CveDB.html | 1563 ++++----- .../data/nvdcve/DatabaseProperties.html | 281 +- .../data/nvdcve/DriverLoader.html | 253 +- .../data/nvdcve/DriverShim.html | 371 ++- .../data/nvdcve/package-frame.html | 2 +- .../data/nvdcve/package-summary.html | 2 +- .../data/update/BaseUpdater.html | 101 + .../data/update/CpeUpdater.html | 211 ++ .../data/update/EngineVersionCheck.html | 194 +- .../data/update/NvdCveUpdater.html | 311 +- .../data/update/cpe/CPEHandler.html | 377 +++ .../dependencycheck/data/update/cpe/Cpe.html | 138 + .../data/update/cpe/package-frame.html | 30 + .../data/update/cpe/package-summary.html | 79 + .../data/update/exception/package-frame.html | 2 +- .../update/exception/package-summary.html | 2 +- .../data/update/nvd/DownloadTask.html | 312 ++ .../data/update/nvd/NvdCve12Handler.html | 256 ++ .../data/update/nvd/NvdCve20Handler.html | 508 +++ .../data/update/nvd/NvdCveInfo.html | 150 + .../data/update/nvd/ProcessTask.html | 196 ++ .../data/update/nvd/UpdateableNvdCve.html | 197 ++ .../data/update/nvd/package-frame.html | 42 + .../data/update/nvd/package-summary.html | 99 + .../data/update/package-frame.html | 17 +- .../data/update/package-summary.html | 27 +- .../dependency/Dependency.html | 1424 ++++---- .../dependencycheck/dependency/Evidence.html | 552 ++- .../dependency/EvidenceCollection.html | 52 +- .../dependency/VulnerableSoftware.html | 645 ++-- .../dependency/package-frame.html | 2 +- .../dependency/package-summary.html | 2 +- .../exception/package-frame.html | 2 +- .../exception/package-summary.html | 2 +- .../owasp/dependencycheck/package-frame.html | 2 +- .../dependencycheck/package-summary.html | 2 +- .../dependencycheck/reporting/EscapeTool.html | 12 +- .../reporting/ReportGenerator.html | 185 +- .../reporting/VelocityLoggerRedirect.html | 119 +- .../reporting/package-frame.html | 2 +- .../reporting/package-summary.html | 2 +- .../suppression/SuppressionErrorHandler.html | 8 +- .../suppression/SuppressionParser.html | 205 +- .../suppression/package-frame.html | 2 +- .../suppression/package-summary.html | 2 +- .../owasp/dependencycheck/utils/DBUtils.html | 12 +- .../dependencycheck/utils/ExtractionUtil.html | 573 ++-- .../utils/FileFilterBuilder.html | 151 + .../dependencycheck/utils/package-frame.html | 5 +- .../utils/package-summary.html | 7 +- .../dependencycheck/xml/pom/PomParser.html | 173 +- .../dependencycheck/xml/pom/PomUtils.html | 158 +- .../xml/pom/package-frame.html | 2 +- .../xml/pom/package-summary.html | 2 +- .../xref/overview-frame.html | 10 +- .../xref/overview-summary.html | 16 +- .../2.3/taskArtifacts/cache.properties | 1 + .../2.3/taskArtifacts/cache.properties.lock | Bin 0 -> 17 bytes .../.gradle/2.3/taskArtifacts/fileHashes.bin | Bin 0 -> 31277 bytes .../2.3/taskArtifacts/fileSnapshots.bin | Bin 0 -> 101397 bytes .../2.3/taskArtifacts/outputFileStates.bin | Bin 0 -> 18842 bytes .../2.3/taskArtifacts/taskArtifacts.bin | Bin 0 -> 24660 bytes .../css/apache-maven-fluido-1.3.1.min.css | 9 + dependency-check-gradle/css/print.css | 23 + dependency-check-gradle/css/site.css | 1 + .../images/accessories-text-editor.png | Bin 0 -> 746 bytes dependency-check-gradle/images/add.gif | Bin 0 -> 397 bytes .../images/apache-maven-project-2.png | Bin 0 -> 33442 bytes .../images/application-certificate.png | Bin 0 -> 923 bytes .../images/contact-new.png | Bin 0 -> 736 bytes dependency-check-gradle/images/dc-gradle.svg | 184 + .../images/document-properties.png | Bin 0 -> 577 bytes .../images/drive-harddisk.png | Bin 0 -> 700 bytes dependency-check-gradle/images/fix.gif | Bin 0 -> 366 bytes .../images/icon_error_sml.gif | Bin 0 -> 633 bytes .../images/icon_help_sml.gif | Bin 0 -> 1072 bytes .../images/icon_info_sml.gif | Bin 0 -> 638 bytes .../images/icon_success_sml.gif | Bin 0 -> 604 bytes .../images/icon_warning_sml.gif | Bin 0 -> 625 bytes .../images/image-x-generic.png | Bin 0 -> 662 bytes .../images/internet-web-browser.png | Bin 0 -> 1017 bytes .../images/logos/build-by-maven-black.png | Bin 0 -> 2294 bytes .../images/logos/build-by-maven-white.png | Bin 0 -> 2260 bytes .../images/logos/maven-feather.png | Bin 0 -> 3330 bytes .../images/network-server.png | Bin 0 -> 536 bytes .../images/package-x-generic.png | Bin 0 -> 717 bytes .../images/profiles/pre-release.png | Bin 0 -> 32607 bytes .../images/profiles/retired.png | Bin 0 -> 22003 bytes .../images/profiles/sandbox.png | Bin 0 -> 33010 bytes dependency-check-gradle/images/remove.gif | Bin 0 -> 607 bytes dependency-check-gradle/images/rss.png | Bin 0 -> 474 bytes dependency-check-gradle/images/update.gif | Bin 0 -> 1090 bytes dependency-check-gradle/images/window-new.png | Bin 0 -> 583 bytes .../img/glyphicons-halflings-white.png | Bin 0 -> 8777 bytes .../img/glyphicons-halflings.png | Bin 0 -> 12799 bytes dependency-check-gradle/index.html | 167 + dependency-check-gradle/issue-tracking.html | 206 ++ .../js/apache-maven-fluido-1.3.1.min.js | 21 + dependency-check-gradle/license.html | 408 +++ dependency-check-gradle/mail-lists.html | 214 ++ dependency-check-gradle/project-info.html | 225 ++ dependency-check-gradle/project-summary.html | 245 ++ .../source-repository.html | 219 ++ dependency-check-gradle/team-list.html | 270 ++ dependency-check-jenkins/index.html | 10 +- dependency-check-jenkins/issue-tracking.html | 10 +- dependency-check-jenkins/license.html | 10 +- dependency-check-jenkins/mail-lists.html | 10 +- dependency-check-jenkins/project-info.html | 10 +- dependency-check-jenkins/project-summary.html | 12 +- .../source-repository.html | 20 +- dependency-check-jenkins/team-list.html | 10 +- dependency-check-maven/aggregate-mojo.html | 65 +- .../apidocs/allclasses-frame.html | 9 +- .../apidocs/allclasses-noframe.html | 9 +- .../apidocs/constant-values.html | 18 +- .../apidocs/deprecated-list.html | 18 +- dependency-check-maven/apidocs/help-doc.html | 22 +- dependency-check-maven/apidocs/index-all.html | 157 +- dependency-check-maven/apidocs/index.html | 11 +- .../dependencycheck/maven/AggregateMojo.html | 16 +- .../maven/BaseDependencyCheckMojo.html | 14 +- .../dependencycheck/maven/CheckMojo.html | 14 +- .../owasp/dependencycheck/maven/Engine.html | 20 +- .../owasp/dependencycheck/maven/HelpMojo.html | 22 +- .../dependencycheck/maven/UpdateMojo.html | 14 +- .../maven/class-use/AggregateMojo.html | 14 +- .../class-use/BaseDependencyCheckMojo.html | 31 +- .../maven/class-use/CheckMojo.html | 14 +- .../maven/class-use/Engine.html | 31 +- .../maven/class-use/HelpMojo.html | 14 +- .../maven/class-use/UpdateMojo.html | 14 +- .../dependencycheck/maven/package-frame.html | 6 +- .../maven/package-summary.html | 20 +- .../dependencycheck/maven/package-tree.html | 24 +- .../dependencycheck/maven/package-use.html | 31 +- .../maven/slf4j/MavenLoggerAdapter.html | 772 +++++ .../maven/slf4j/MavenLoggerFactory.html | 278 ++ .../slf4j/class-use/MavenLoggerAdapter.html | 117 + .../slf4j/class-use/MavenLoggerFactory.html | 117 + .../maven/slf4j/package-frame.html | 21 + .../maven/slf4j/package-summary.html | 152 + .../maven/slf4j/package-tree.html | 135 + .../maven/slf4j/package-use.html | 117 + .../org/slf4j/impl/StaticLoggerBinder.html | 334 ++ .../impl/class-use/StaticLoggerBinder.html | 161 + .../apidocs/org/slf4j/impl/package-frame.html | 20 + .../org/slf4j/impl/package-summary.html | 147 + .../apidocs/org/slf4j/impl/package-tree.html | 130 + .../apidocs/org/slf4j/impl/package-use.html | 155 + .../apidocs/overview-frame.html | 23 + .../apidocs/overview-summary.html | 145 + .../apidocs/overview-tree.html | 27 +- dependency-check-maven/apidocs/package-list | 2 + .../apidocs/serialized-form.html | 144 + dependency-check-maven/check-mojo.html | 63 +- dependency-check-maven/checkstyle.html | 48 +- dependency-check-maven/checkstyle.rss | 602 ++-- .../cobertura/frame-packages.html | 6 + ...files-org.owasp.dependencycheck.maven.html | 2 +- ...org.owasp.dependencycheck.maven.slf4j.html | 26 + .../frame-sourcefiles-org.slf4j.impl.html | 23 + .../cobertura/frame-sourcefiles.html | 11 +- ...mmary-org.owasp.dependencycheck.maven.html | 15 +- ...org.owasp.dependencycheck.maven.slf4j.html | 44 + .../frame-summary-org.slf4j.impl.html | 42 + .../cobertura/frame-summary.html | 8 +- ...p.dependencycheck.maven.AggregateMojo.html | 615 ++-- ...cycheck.maven.BaseDependencyCheckMojo.html | 2276 ++++++------- ...owasp.dependencycheck.maven.CheckMojo.html | 202 +- ...rg.owasp.dependencycheck.maven.Engine.html | 550 +-- ....owasp.dependencycheck.maven.HelpMojo.html | 963 +++--- ...wasp.dependencycheck.maven.UpdateMojo.html | 166 +- ...ycheck.maven.slf4j.MavenLoggerAdapter.html | 556 ++++ ...ycheck.maven.slf4j.MavenLoggerFactory.html | 132 + .../org.slf4j.impl.StaticLoggerBinder.html | 221 ++ dependency-check-maven/configuration.html | 27 +- dependency-check-maven/cpd.html | 275 ++ .../dependency-updates-report.html | 1080 +++++- dependency-check-maven/findbugs.html | 53 +- dependency-check-maven/help-mojo.html | 14 +- dependency-check-maven/index.html | 24 +- dependency-check-maven/issue-tracking.html | 12 +- dependency-check-maven/license.html | 12 +- dependency-check-maven/mail-lists.html | 12 +- dependency-check-maven/plugin-info.html | 29 +- .../plugin-updates-report.html | 102 +- dependency-check-maven/pmd.html | 58 +- dependency-check-maven/project-info.html | 12 +- dependency-check-maven/project-reports.html | 30 +- dependency-check-maven/project-summary.html | 14 +- dependency-check-maven/source-repository.html | 12 +- dependency-check-maven/surefire-report.html | 31 +- dependency-check-maven/taglist.html | 25 +- dependency-check-maven/team-list.html | 19 +- dependency-check-maven/update-only-mojo.html | 63 +- dependency-check-maven/xref-test/index.html | 2 +- .../maven/BaseDependencyCheckMojoTest.html | 2 +- .../dependencycheck/maven/package-frame.html | 2 +- .../maven/package-summary.html | 2 +- .../xref-test/overview-frame.html | 2 +- .../xref-test/overview-summary.html | 4 +- .../xref/allclasses-frame.html | 9 + dependency-check-maven/xref/index.html | 2 +- .../dependencycheck/maven/AggregateMojo.html | 489 +-- .../maven/BaseDependencyCheckMojo.html | 1976 +++++------ .../dependencycheck/maven/CheckMojo.html | 189 +- .../owasp/dependencycheck/maven/Engine.html | 413 +-- .../owasp/dependencycheck/maven/HelpMojo.html | 829 +++-- .../dependencycheck/maven/UpdateMojo.html | 153 +- .../dependencycheck/maven/package-frame.html | 2 +- .../maven/package-summary.html | 2 +- .../maven/slf4j/MavenLoggerAdapter.html | 348 ++ .../maven/slf4j/MavenLoggerFactory.html | 69 + .../maven/slf4j/package-frame.html | 27 + .../maven/slf4j/package-summary.html | 74 + .../org/slf4j/impl/StaticLoggerBinder.html | 118 + .../xref/org/slf4j/impl/package-frame.html | 24 + .../xref/org/slf4j/impl/package-summary.html | 69 + .../xref/overview-frame.html | 8 +- .../xref/overview-summary.html | 14 +- .../apidocs/allclasses-frame.html | 8 +- .../apidocs/allclasses-noframe.html | 8 +- .../apidocs/constant-values.html | 90 +- .../apidocs/deprecated-list.html | 12 +- dependency-check-utils/apidocs/help-doc.html | 8 +- dependency-check-utils/apidocs/index-all.html | 60 +- dependency-check-utils/apidocs/index.html | 4 +- .../org/apache/tools/ant/BuildException.html | 8 +- .../apache/tools/ant/DirectoryScanner.html | 8 +- .../org/apache/tools/ant/FileScanner.html | 8 +- .../org/apache/tools/ant/Location.html | 8 +- .../org/apache/tools/ant/PathTokenizer.html | 8 +- .../apache/tools/ant/ProjectComponent.html | 8 +- .../tools/ant/class-use/BuildException.html | 8 +- .../tools/ant/class-use/DirectoryScanner.html | 8 +- .../tools/ant/class-use/FileScanner.html | 8 +- .../apache/tools/ant/class-use/Location.html | 8 +- .../tools/ant/class-use/PathTokenizer.html | 8 +- .../tools/ant/class-use/ProjectComponent.html | 8 +- .../org/apache/tools/ant/launch/Locator.html | 8 +- .../tools/ant/launch/class-use/Locator.html | 8 +- .../tools/ant/launch/package-frame.html | 6 +- .../tools/ant/launch/package-summary.html | 8 +- .../apache/tools/ant/launch/package-tree.html | 8 +- .../apache/tools/ant/launch/package-use.html | 8 +- .../org/apache/tools/ant/package-frame.html | 6 +- .../org/apache/tools/ant/package-summary.html | 8 +- .../org/apache/tools/ant/package-tree.html | 8 +- .../org/apache/tools/ant/package-use.html | 8 +- .../ant/taskdefs/condition/Condition.html | 8 +- .../tools/ant/taskdefs/condition/Os.html | 8 +- .../condition/class-use/Condition.html | 8 +- .../ant/taskdefs/condition/class-use/Os.html | 8 +- .../ant/taskdefs/condition/package-frame.html | 6 +- .../taskdefs/condition/package-summary.html | 8 +- .../ant/taskdefs/condition/package-tree.html | 8 +- .../ant/taskdefs/condition/package-use.html | 8 +- .../org/apache/tools/ant/types/DataType.html | 8 +- .../org/apache/tools/ant/types/Reference.html | 8 +- .../org/apache/tools/ant/types/Resource.html | 8 +- .../tools/ant/types/ResourceCollection.html | 8 +- .../tools/ant/types/ResourceFactory.html | 8 +- .../tools/ant/types/class-use/DataType.html | 8 +- .../tools/ant/types/class-use/Reference.html | 8 +- .../tools/ant/types/class-use/Resource.html | 8 +- .../types/class-use/ResourceCollection.html | 8 +- .../ant/types/class-use/ResourceFactory.html | 8 +- .../apache/tools/ant/types/package-frame.html | 6 +- .../tools/ant/types/package-summary.html | 8 +- .../apache/tools/ant/types/package-tree.html | 8 +- .../apache/tools/ant/types/package-use.html | 8 +- .../tools/ant/types/resources/Appendable.html | 8 +- .../ant/types/resources/FileProvider.html | 8 +- .../ant/types/resources/FileResource.html | 8 +- .../tools/ant/types/resources/Touchable.html | 8 +- .../types/resources/class-use/Appendable.html | 8 +- .../resources/class-use/FileProvider.html | 8 +- .../resources/class-use/FileResource.html | 8 +- .../types/resources/class-use/Touchable.html | 8 +- .../ant/types/resources/package-frame.html | 6 +- .../ant/types/resources/package-summary.html | 8 +- .../ant/types/resources/package-tree.html | 8 +- .../ant/types/resources/package-use.html | 8 +- .../ant/types/selectors/FileSelector.html | 8 +- .../ant/types/selectors/SelectorScanner.html | 8 +- .../ant/types/selectors/SelectorUtils.html | 8 +- .../ant/types/selectors/TokenizedPath.html | 8 +- .../ant/types/selectors/TokenizedPattern.html | 8 +- .../selectors/class-use/FileSelector.html | 8 +- .../selectors/class-use/SelectorScanner.html | 8 +- .../selectors/class-use/SelectorUtils.html | 8 +- .../selectors/class-use/TokenizedPath.html | 8 +- .../selectors/class-use/TokenizedPattern.html | 8 +- .../ant/types/selectors/package-frame.html | 6 +- .../ant/types/selectors/package-summary.html | 8 +- .../ant/types/selectors/package-tree.html | 8 +- .../ant/types/selectors/package-use.html | 8 +- .../CollectionUtils.EmptyEnumeration.html | 8 +- .../tools/ant/util/CollectionUtils.html | 8 +- .../org/apache/tools/ant/util/FileUtils.html | 8 +- .../tools/ant/util/SymbolicLinkUtils.html | 8 +- .../org/apache/tools/ant/util/VectorSet.html | 8 +- .../CollectionUtils.EmptyEnumeration.html | 8 +- .../ant/util/class-use/CollectionUtils.html | 8 +- .../tools/ant/util/class-use/FileUtils.html | 8 +- .../ant/util/class-use/SymbolicLinkUtils.html | 8 +- .../tools/ant/util/class-use/VectorSet.html | 8 +- .../apache/tools/ant/util/package-frame.html | 6 +- .../tools/ant/util/package-summary.html | 8 +- .../apache/tools/ant/util/package-tree.html | 8 +- .../apache/tools/ant/util/package-use.html | 8 +- .../owasp/dependencycheck/utils/Checksum.html | 8 +- .../utils/DownloadFailedException.html | 8 +- .../dependencycheck/utils/Downloader.html | 8 +- .../utils/ExtractionException.html | 8 +- .../dependencycheck/utils/FileUtils.html | 26 +- .../utils/InvalidSettingException.html | 12 +- .../dependencycheck/utils/Settings.KEYS.html | 154 +- .../owasp/dependencycheck/utils/Settings.html | 24 +- .../utils/URLConnectionFactory.html | 8 +- .../utils/URLConnectionFailureException.html | 8 +- .../utils/class-use/Checksum.html | 8 +- .../class-use/DownloadFailedException.html | 8 +- .../utils/class-use/Downloader.html | 8 +- .../utils/class-use/ExtractionException.html | 8 +- .../utils/class-use/FileUtils.html | 8 +- .../class-use/InvalidSettingException.html | 13 +- .../utils/class-use/Settings.KEYS.html | 8 +- .../utils/class-use/Settings.html | 8 +- .../utils/class-use/URLConnectionFactory.html | 8 +- .../URLConnectionFailureException.html | 8 +- .../dependencycheck/utils/package-frame.html | 8 +- .../utils/package-summary.html | 20 +- .../dependencycheck/utils/package-tree.html | 10 +- .../dependencycheck/utils/package-use.html | 8 +- .../apidocs/overview-frame.html | 6 +- .../apidocs/overview-summary.html | 10 +- .../apidocs/overview-tree.html | 10 +- .../apidocs/serialized-form.html | 8 +- dependency-check-utils/checkstyle.html | 12 +- dependency-check-utils/checkstyle.rss | 30 +- ...files-org.owasp.dependencycheck.utils.html | 10 +- .../cobertura/frame-sourcefiles.html | 10 +- ....dependencycheck.org.apache.tools.ant.html | 2 +- ...encycheck.org.apache.tools.ant.launch.html | 2 +- ...g.apache.tools.ant.taskdefs.condition.html | 2 +- ...dencycheck.org.apache.tools.ant.types.html | 2 +- ....org.apache.tools.ant.types.resources.html | 2 +- ....org.apache.tools.ant.types.selectors.html | 2 +- ...ndencycheck.org.apache.tools.ant.util.html | 2 +- ...mmary-org.owasp.dependencycheck.utils.html | 16 +- .../cobertura/frame-summary.html | 6 +- ...k.org.apache.tools.ant.BuildException.html | 2 +- ...org.apache.tools.ant.DirectoryScanner.html | 434 +-- ...heck.org.apache.tools.ant.FileScanner.html | 2 +- ...cycheck.org.apache.tools.ant.Location.html | 2 +- ...ck.org.apache.tools.ant.PathTokenizer.html | 2 +- ...org.apache.tools.ant.ProjectComponent.html | 2 +- ...k.org.apache.tools.ant.launch.Locator.html | 2 +- ...ools.ant.taskdefs.condition.Condition.html | 2 +- ...pache.tools.ant.taskdefs.condition.Os.html | 82 +- ...k.org.apache.tools.ant.types.DataType.html | 2 +- ....org.apache.tools.ant.types.Reference.html | 2 +- ...k.org.apache.tools.ant.types.Resource.html | 2 +- ...he.tools.ant.types.ResourceCollection.html | 2 +- ...pache.tools.ant.types.ResourceFactory.html | 2 +- ....tools.ant.types.resources.Appendable.html | 2 +- ...ools.ant.types.resources.FileProvider.html | 2 +- ...ools.ant.types.resources.FileResource.html | 2 +- ...e.tools.ant.types.resources.Touchable.html | 2 +- ...ools.ant.types.selectors.FileSelector.html | 2 +- ...s.ant.types.selectors.SelectorScanner.html | 2 +- ...ols.ant.types.selectors.SelectorUtils.html | 256 +- ...ols.ant.types.selectors.TokenizedPath.html | 40 +- ....ant.types.selectors.TokenizedPattern.html | 50 +- ...apache.tools.ant.util.CollectionUtils.html | 18 +- ...k.org.apache.tools.ant.util.FileUtils.html | 130 +- ...ache.tools.ant.util.SymbolicLinkUtils.html | 12 +- ...k.org.apache.tools.ant.util.VectorSet.html | 32 +- ....owasp.dependencycheck.utils.Checksum.html | 318 +- ...cycheck.utils.DownloadFailedException.html | 2 +- ...wasp.dependencycheck.utils.Downloader.html | 679 ++-- ...ndencycheck.utils.ExtractionException.html | 2 +- ...owasp.dependencycheck.utils.FileUtils.html | 165 +- ...cycheck.utils.InvalidSettingException.html | 6 +- ....owasp.dependencycheck.utils.Settings.html | 1857 ++++++----- ...dencycheck.utils.URLConnectionFactory.html | 2 +- ...k.utils.URLConnectionFailureException.html | 2 +- dependency-check-utils/cpd.html | 10 +- .../dependency-updates-report.html | 1096 +++++- dependency-check-utils/findbugs.html | 12 +- dependency-check-utils/index.html | 10 +- dependency-check-utils/issue-tracking.html | 10 +- dependency-check-utils/license.html | 10 +- dependency-check-utils/mail-lists.html | 10 +- .../plugin-updates-report.html | 89 +- dependency-check-utils/pmd.html | 21 +- dependency-check-utils/project-info.html | 10 +- dependency-check-utils/project-reports.html | 10 +- dependency-check-utils/project-summary.html | 12 +- dependency-check-utils/source-repository.html | 10 +- dependency-check-utils/surefire-report.html | 60 +- dependency-check-utils/taglist.html | 12 +- dependency-check-utils/team-list.html | 17 +- dependency-check-utils/xref-test/index.html | 2 +- .../org/apache/tools/ant/package-frame.html | 2 +- .../org/apache/tools/ant/package-summary.html | 2 +- .../dependencycheck/utils/SettingsTest.html | 34 +- .../dependencycheck/utils/package-frame.html | 2 +- .../utils/package-summary.html | 2 +- .../xref-test/overview-frame.html | 2 +- .../xref-test/overview-summary.html | 4 +- .../xref/allclasses-frame.html | 6 - dependency-check-utils/xref/index.html | 2 +- .../tools/ant/launch/package-frame.html | 2 +- .../tools/ant/launch/package-summary.html | 2 +- .../org/apache/tools/ant/package-frame.html | 2 +- .../org/apache/tools/ant/package-summary.html | 2 +- .../ant/taskdefs/condition/package-frame.html | 2 +- .../taskdefs/condition/package-summary.html | 2 +- .../apache/tools/ant/types/package-frame.html | 2 +- .../tools/ant/types/package-summary.html | 2 +- .../ant/types/resources/package-frame.html | 2 +- .../ant/types/resources/package-summary.html | 2 +- .../ant/types/selectors/package-frame.html | 2 +- .../ant/types/selectors/package-summary.html | 2 +- .../apache/tools/ant/util/package-frame.html | 2 +- .../tools/ant/util/package-summary.html | 2 +- .../owasp/dependencycheck/utils/Checksum.html | 263 +- .../dependencycheck/utils/Downloader.html | 529 +-- .../dependencycheck/utils/FileUtils.html | 138 +- .../owasp/dependencycheck/utils/Settings.html | 1498 ++++----- .../dependencycheck/utils/package-frame.html | 8 +- .../utils/package-summary.html | 12 +- .../xref/overview-frame.html | 2 +- .../xref/overview-summary.html | 4 +- dependency-check.1.3.xsd | 8 +- general/internals.html | 12 +- general/suppression.html | 12 +- general/thereport.html | 12 +- index.html | 16 +- issue-tracking.html | 12 +- license.html | 12 +- mail-lists.html | 12 +- modules.html | 21 +- project-info.html | 12 +- project-summary.html | 14 +- related.html | 12 +- source-repository.html | 12 +- team-list.html | 12 +- 1212 files changed, 86425 insertions(+), 43448 deletions(-) create mode 100644 analyzers/autoconf-analyzer.html create mode 100644 analyzers/openssl-analyzer.html create mode 100644 dependency-check-ant/apidocs/org/owasp/dependencycheck/ant/logging/AntLoggerAdapter.html create mode 100644 dependency-check-ant/apidocs/org/owasp/dependencycheck/ant/logging/AntLoggerFactory.html create mode 100644 dependency-check-ant/apidocs/org/owasp/dependencycheck/ant/logging/class-use/AntLoggerAdapter.html create mode 100644 dependency-check-ant/apidocs/org/owasp/dependencycheck/ant/logging/class-use/AntLoggerFactory.html create mode 100644 dependency-check-ant/apidocs/org/owasp/dependencycheck/ant/logging/package-frame.html create mode 100644 dependency-check-ant/apidocs/org/owasp/dependencycheck/ant/logging/package-summary.html create mode 100644 dependency-check-ant/apidocs/org/owasp/dependencycheck/ant/logging/package-tree.html create mode 100644 dependency-check-ant/apidocs/org/owasp/dependencycheck/ant/logging/package-use.html create mode 100644 dependency-check-ant/apidocs/org/slf4j/impl/StaticLoggerBinder.html create mode 100644 dependency-check-ant/apidocs/org/slf4j/impl/class-use/StaticLoggerBinder.html create mode 100644 dependency-check-ant/apidocs/org/slf4j/impl/package-frame.html create mode 100644 dependency-check-ant/apidocs/org/slf4j/impl/package-summary.html create mode 100644 dependency-check-ant/apidocs/org/slf4j/impl/package-tree.html create mode 100644 dependency-check-ant/apidocs/org/slf4j/impl/package-use.html create mode 100644 dependency-check-ant/apidocs/overview-frame.html create mode 100644 dependency-check-ant/apidocs/overview-summary.html create mode 100644 dependency-check-ant/apidocs/serialized-form.html create mode 100644 dependency-check-ant/cobertura/frame-sourcefiles-org.owasp.dependencycheck.ant.logging.html create mode 100644 dependency-check-ant/cobertura/frame-sourcefiles-org.slf4j.impl.html create mode 100644 dependency-check-ant/cobertura/frame-summary-org.owasp.dependencycheck.ant.logging.html create mode 100644 dependency-check-ant/cobertura/frame-summary-org.slf4j.impl.html create mode 100644 dependency-check-ant/cobertura/org.owasp.dependencycheck.ant.logging.AntLoggerAdapter.html create mode 100644 dependency-check-ant/cobertura/org.owasp.dependencycheck.ant.logging.AntLoggerFactory.html create mode 100644 dependency-check-ant/cobertura/org.slf4j.impl.StaticLoggerBinder.html create mode 100644 dependency-check-ant/xref/org/owasp/dependencycheck/ant/logging/AntLoggerAdapter.html create mode 100644 dependency-check-ant/xref/org/owasp/dependencycheck/ant/logging/AntLoggerFactory.html create mode 100644 dependency-check-ant/xref/org/owasp/dependencycheck/ant/logging/package-frame.html create mode 100644 dependency-check-ant/xref/org/owasp/dependencycheck/ant/logging/package-summary.html create mode 100644 dependency-check-ant/xref/org/slf4j/impl/StaticLoggerBinder.html create mode 100644 dependency-check-ant/xref/org/slf4j/impl/package-frame.html create mode 100644 dependency-check-ant/xref/org/slf4j/impl/package-summary.html create mode 100644 dependency-check-cli/cpd.html create mode 100644 dependency-check-cli/xref-test/org/owasp/dependencycheck/AppTest.html create mode 100644 dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/AutoconfAnalyzer.html create mode 100644 dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/CMakeAnalyzer.html create mode 100644 dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/OpenSSLAnalyzer.html create mode 100644 dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/AutoconfAnalyzer.html create mode 100644 dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/CMakeAnalyzer.html create mode 100644 dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/OpenSSLAnalyzer.html create mode 100644 dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/BaseUpdater.html create mode 100644 dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/CpeUpdater.html create mode 100644 dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/class-use/BaseUpdater.html create mode 100644 dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/class-use/CpeUpdater.html create mode 100644 dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/cpe/CPEHandler.Element.html create mode 100644 dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/cpe/CPEHandler.html create mode 100644 dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/cpe/Cpe.html create mode 100644 dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/cpe/class-use/CPEHandler.Element.html create mode 100644 dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/cpe/class-use/CPEHandler.html create mode 100644 dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/cpe/class-use/Cpe.html create mode 100644 dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/cpe/package-frame.html create mode 100644 dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/cpe/package-summary.html create mode 100644 dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/cpe/package-tree.html create mode 100644 dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/cpe/package-use.html create mode 100644 dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/DownloadTask.html create mode 100644 dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/NvdCve12Handler.Element.html create mode 100644 dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/NvdCve12Handler.html create mode 100644 dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/NvdCve20Handler.Element.html create mode 100644 dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/NvdCve20Handler.html create mode 100644 dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/NvdCveInfo.html create mode 100644 dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/ProcessTask.html create mode 100644 dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/UpdateableNvdCve.html create mode 100644 dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/class-use/DownloadTask.html create mode 100644 dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/class-use/NvdCve12Handler.Element.html create mode 100644 dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/class-use/NvdCve12Handler.html create mode 100644 dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/class-use/NvdCve20Handler.Element.html create mode 100644 dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/class-use/NvdCve20Handler.html create mode 100644 dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/class-use/NvdCveInfo.html create mode 100644 dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/class-use/ProcessTask.html create mode 100644 dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/class-use/UpdateableNvdCve.html create mode 100644 dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/package-frame.html create mode 100644 dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/package-summary.html create mode 100644 dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/package-tree.html create mode 100644 dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/package-use.html create mode 100644 dependency-check-core/apidocs/org/owasp/dependencycheck/utils/FileFilterBuilder.html create mode 100644 dependency-check-core/apidocs/org/owasp/dependencycheck/utils/class-use/FileFilterBuilder.html create mode 100644 dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.data.update.cpe.html create mode 100644 dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.data.update.nvd.html create mode 100644 dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.update.cpe.html create mode 100644 dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.update.nvd.html create mode 100644 dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AutoconfAnalyzer.html create mode 100644 dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.CMakeAnalyzer.html create mode 100644 dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.OpenSSLAnalyzer.html create mode 100644 dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.BaseUpdater.html create mode 100644 dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.CpeUpdater.html create mode 100644 dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.cpe.CPEHandler.html create mode 100644 dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.cpe.Cpe.html create mode 100644 dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.DownloadTask.html create mode 100644 dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.NvdCve12Handler.html create mode 100644 dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.NvdCve20Handler.html create mode 100644 dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.NvdCveInfo.html create mode 100644 dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.ProcessTask.html create mode 100644 dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.UpdateableNvdCve.html create mode 100644 dependency-check-core/cobertura/org.owasp.dependencycheck.utils.FileFilterBuilder.html create mode 100644 dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/AutoconfAnalyzerTest.html create mode 100644 dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/CMakeAnalyzerTest.html create mode 100644 dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzerIntegrationTest.html create mode 100644 dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/OpenSSLAnalyzerTest.html create mode 100644 dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/BaseUpdaterTest.html create mode 100644 dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/CpeUpdaterIntegrationTest.html create mode 100644 dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/DownloadTaskTest.html create mode 100644 dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCveInfoTest.html create mode 100644 dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCveUpdaterIntegrationTest.html create mode 100644 dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCve_1_2_HandlerTest.html create mode 100644 dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCve_2_0_HandlerTest.html create mode 100644 dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/UpdateableNvdCveTest.html create mode 100644 dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/package-frame.html create mode 100644 dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/package-summary.html create mode 100644 dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AutoconfAnalyzer.html create mode 100644 dependency-check-core/xref/org/owasp/dependencycheck/analyzer/CMakeAnalyzer.html create mode 100644 dependency-check-core/xref/org/owasp/dependencycheck/analyzer/OpenSSLAnalyzer.html create mode 100644 dependency-check-core/xref/org/owasp/dependencycheck/data/update/BaseUpdater.html create mode 100644 dependency-check-core/xref/org/owasp/dependencycheck/data/update/CpeUpdater.html create mode 100644 dependency-check-core/xref/org/owasp/dependencycheck/data/update/cpe/CPEHandler.html create mode 100644 dependency-check-core/xref/org/owasp/dependencycheck/data/update/cpe/Cpe.html create mode 100644 dependency-check-core/xref/org/owasp/dependencycheck/data/update/cpe/package-frame.html create mode 100644 dependency-check-core/xref/org/owasp/dependencycheck/data/update/cpe/package-summary.html create mode 100644 dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/DownloadTask.html create mode 100644 dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/NvdCve12Handler.html create mode 100644 dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/NvdCve20Handler.html create mode 100644 dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/NvdCveInfo.html create mode 100644 dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/ProcessTask.html create mode 100644 dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/UpdateableNvdCve.html create mode 100644 dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/package-frame.html create mode 100644 dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/package-summary.html create mode 100644 dependency-check-core/xref/org/owasp/dependencycheck/utils/FileFilterBuilder.html create mode 100644 dependency-check-gradle/.gradle/2.3/taskArtifacts/cache.properties create mode 100644 dependency-check-gradle/.gradle/2.3/taskArtifacts/cache.properties.lock create mode 100644 dependency-check-gradle/.gradle/2.3/taskArtifacts/fileHashes.bin create mode 100644 dependency-check-gradle/.gradle/2.3/taskArtifacts/fileSnapshots.bin create mode 100644 dependency-check-gradle/.gradle/2.3/taskArtifacts/outputFileStates.bin create mode 100644 dependency-check-gradle/.gradle/2.3/taskArtifacts/taskArtifacts.bin create mode 100644 dependency-check-gradle/css/apache-maven-fluido-1.3.1.min.css create mode 100644 dependency-check-gradle/css/print.css create mode 100644 dependency-check-gradle/css/site.css create mode 100644 dependency-check-gradle/images/accessories-text-editor.png create mode 100644 dependency-check-gradle/images/add.gif create mode 100644 dependency-check-gradle/images/apache-maven-project-2.png create mode 100644 dependency-check-gradle/images/application-certificate.png create mode 100644 dependency-check-gradle/images/contact-new.png create mode 100644 dependency-check-gradle/images/dc-gradle.svg create mode 100644 dependency-check-gradle/images/document-properties.png create mode 100644 dependency-check-gradle/images/drive-harddisk.png create mode 100644 dependency-check-gradle/images/fix.gif create mode 100644 dependency-check-gradle/images/icon_error_sml.gif create mode 100644 dependency-check-gradle/images/icon_help_sml.gif create mode 100644 dependency-check-gradle/images/icon_info_sml.gif create mode 100644 dependency-check-gradle/images/icon_success_sml.gif create mode 100644 dependency-check-gradle/images/icon_warning_sml.gif create mode 100644 dependency-check-gradle/images/image-x-generic.png create mode 100644 dependency-check-gradle/images/internet-web-browser.png create mode 100644 dependency-check-gradle/images/logos/build-by-maven-black.png create mode 100644 dependency-check-gradle/images/logos/build-by-maven-white.png create mode 100644 dependency-check-gradle/images/logos/maven-feather.png create mode 100644 dependency-check-gradle/images/network-server.png create mode 100644 dependency-check-gradle/images/package-x-generic.png create mode 100644 dependency-check-gradle/images/profiles/pre-release.png create mode 100644 dependency-check-gradle/images/profiles/retired.png create mode 100644 dependency-check-gradle/images/profiles/sandbox.png create mode 100644 dependency-check-gradle/images/remove.gif create mode 100644 dependency-check-gradle/images/rss.png create mode 100644 dependency-check-gradle/images/update.gif create mode 100644 dependency-check-gradle/images/window-new.png create mode 100644 dependency-check-gradle/img/glyphicons-halflings-white.png create mode 100644 dependency-check-gradle/img/glyphicons-halflings.png create mode 100644 dependency-check-gradle/index.html create mode 100644 dependency-check-gradle/issue-tracking.html create mode 100644 dependency-check-gradle/js/apache-maven-fluido-1.3.1.min.js create mode 100644 dependency-check-gradle/license.html create mode 100644 dependency-check-gradle/mail-lists.html create mode 100644 dependency-check-gradle/project-info.html create mode 100644 dependency-check-gradle/project-summary.html create mode 100644 dependency-check-gradle/source-repository.html create mode 100644 dependency-check-gradle/team-list.html create mode 100644 dependency-check-maven/apidocs/org/owasp/dependencycheck/maven/slf4j/MavenLoggerAdapter.html create mode 100644 dependency-check-maven/apidocs/org/owasp/dependencycheck/maven/slf4j/MavenLoggerFactory.html create mode 100644 dependency-check-maven/apidocs/org/owasp/dependencycheck/maven/slf4j/class-use/MavenLoggerAdapter.html create mode 100644 dependency-check-maven/apidocs/org/owasp/dependencycheck/maven/slf4j/class-use/MavenLoggerFactory.html create mode 100644 dependency-check-maven/apidocs/org/owasp/dependencycheck/maven/slf4j/package-frame.html create mode 100644 dependency-check-maven/apidocs/org/owasp/dependencycheck/maven/slf4j/package-summary.html create mode 100644 dependency-check-maven/apidocs/org/owasp/dependencycheck/maven/slf4j/package-tree.html create mode 100644 dependency-check-maven/apidocs/org/owasp/dependencycheck/maven/slf4j/package-use.html create mode 100644 dependency-check-maven/apidocs/org/slf4j/impl/StaticLoggerBinder.html create mode 100644 dependency-check-maven/apidocs/org/slf4j/impl/class-use/StaticLoggerBinder.html create mode 100644 dependency-check-maven/apidocs/org/slf4j/impl/package-frame.html create mode 100644 dependency-check-maven/apidocs/org/slf4j/impl/package-summary.html create mode 100644 dependency-check-maven/apidocs/org/slf4j/impl/package-tree.html create mode 100644 dependency-check-maven/apidocs/org/slf4j/impl/package-use.html create mode 100644 dependency-check-maven/apidocs/overview-frame.html create mode 100644 dependency-check-maven/apidocs/overview-summary.html create mode 100644 dependency-check-maven/apidocs/serialized-form.html create mode 100644 dependency-check-maven/cobertura/frame-sourcefiles-org.owasp.dependencycheck.maven.slf4j.html create mode 100644 dependency-check-maven/cobertura/frame-sourcefiles-org.slf4j.impl.html create mode 100644 dependency-check-maven/cobertura/frame-summary-org.owasp.dependencycheck.maven.slf4j.html create mode 100644 dependency-check-maven/cobertura/frame-summary-org.slf4j.impl.html create mode 100644 dependency-check-maven/cobertura/org.owasp.dependencycheck.maven.slf4j.MavenLoggerAdapter.html create mode 100644 dependency-check-maven/cobertura/org.owasp.dependencycheck.maven.slf4j.MavenLoggerFactory.html create mode 100644 dependency-check-maven/cobertura/org.slf4j.impl.StaticLoggerBinder.html create mode 100644 dependency-check-maven/cpd.html create mode 100644 dependency-check-maven/xref/org/owasp/dependencycheck/maven/slf4j/MavenLoggerAdapter.html create mode 100644 dependency-check-maven/xref/org/owasp/dependencycheck/maven/slf4j/MavenLoggerFactory.html create mode 100644 dependency-check-maven/xref/org/owasp/dependencycheck/maven/slf4j/package-frame.html create mode 100644 dependency-check-maven/xref/org/owasp/dependencycheck/maven/slf4j/package-summary.html create mode 100644 dependency-check-maven/xref/org/slf4j/impl/StaticLoggerBinder.html create mode 100644 dependency-check-maven/xref/org/slf4j/impl/package-frame.html create mode 100644 dependency-check-maven/xref/org/slf4j/impl/package-summary.html diff --git a/analyzers/archive-analyzer.html b/analyzers/archive-analyzer.html index e537d6bb4..74a0cc508 100644 --- a/analyzers/archive-analyzer.html +++ b/analyzers/archive-analyzer.html @@ -1,13 +1,13 @@ - + dependency-check - Archive Analyzer @@ -62,9 +62,9 @@ -
  • | Last Published: 2015-05-13
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -143,7 +143,7 @@ - +
  • @@ -197,9 +197,23 @@ Nuspec Analyzer
  • + +
  • + + + + Autoconf Analyzer +
  • + +
  • + + + + OpenSSL Analyzer +
  • - +
  • diff --git a/analyzers/assembly-analyzer.html b/analyzers/assembly-analyzer.html index 5a84747ce..17f8ba8dd 100644 --- a/analyzers/assembly-analyzer.html +++ b/analyzers/assembly-analyzer.html @@ -1,13 +1,13 @@ - + dependency-check - Assembly Analyzer @@ -62,9 +62,9 @@ -
  • | Last Published: 2015-05-13
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -143,7 +143,7 @@ - +
  • @@ -197,9 +197,23 @@ Nuspec Analyzer
  • + +
  • + + + + Autoconf Analyzer +
  • + +
  • + + + + OpenSSL Analyzer +
  • - +
  • diff --git a/analyzers/autoconf-analyzer.html b/analyzers/autoconf-analyzer.html new file mode 100644 index 000000000..be75a46aa --- /dev/null +++ b/analyzers/autoconf-analyzer.html @@ -0,0 +1,297 @@ + + + + + + + + + dependency-check - Autoconf Analyzer + + + + + + + + + + + + + + + + + + + + + Fork me on GitHub + + + + + +
    + + + + + +
    +
    + +
    + + +
    + +

    Autoconf Analyzer

    +

    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

    +
    +
    +
    + +
    + +
    +
    +
    +

    Copyright © 2012–2015 + OWASP. + All rights reserved. + +

    +
    + + + +
    +
    + + diff --git a/analyzers/central-analyzer.html b/analyzers/central-analyzer.html index 60ca33e8b..0d5af1528 100644 --- a/analyzers/central-analyzer.html +++ b/analyzers/central-analyzer.html @@ -1,13 +1,13 @@ - + dependency-check - Central Analyzer @@ -62,9 +62,9 @@ -
  • | Last Published: 2015-05-13
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -143,7 +143,7 @@ - +
  • @@ -197,9 +197,23 @@ Nuspec Analyzer
  • + +
  • + + + + Autoconf Analyzer +
  • + +
  • + + + + OpenSSL Analyzer +
  • - +
  • diff --git a/analyzers/index.html b/analyzers/index.html index 7e683a605..aa41abcb7 100644 --- a/analyzers/index.html +++ b/analyzers/index.html @@ -1,13 +1,13 @@ - + dependency-check - File Type Analyzers @@ -62,9 +62,9 @@ -
  • | Last Published: 2015-05-13
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -143,7 +143,7 @@ - +
  • File Type Analyzers @@ -197,9 +197,23 @@ Nuspec Analyzer
  • + +
  • + + + + Autoconf Analyzer +
  • + +
  • + + + + OpenSSL Analyzer +
  • - +
  • @@ -265,6 +279,8 @@
  • Assembly Analyzer
  • +
  • Autoconf Analyzer
  • +
  • Central Analyzer
  • Jar Analyzer
  • @@ -273,6 +289,8 @@
  • Nuspec Analyzer
  • +
  • OpenSSL Analyzer
  • +
  • Python Analyzer
  • diff --git a/analyzers/jar-analyzer.html b/analyzers/jar-analyzer.html index abb87b620..d8581e2f0 100644 --- a/analyzers/jar-analyzer.html +++ b/analyzers/jar-analyzer.html @@ -1,13 +1,13 @@ - + dependency-check - Jar Analyzer @@ -62,9 +62,9 @@ -
  • | Last Published: 2015-05-13
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -143,7 +143,7 @@ - +
  • @@ -197,9 +197,23 @@ Nuspec Analyzer
  • + +
  • + + + + Autoconf Analyzer +
  • + +
  • + + + + OpenSSL Analyzer +
  • - +
  • diff --git a/analyzers/nexus-analyzer.html b/analyzers/nexus-analyzer.html index 552b2beb4..659ebea95 100644 --- a/analyzers/nexus-analyzer.html +++ b/analyzers/nexus-analyzer.html @@ -1,13 +1,13 @@ - + dependency-check - Nexus Analyzer @@ -62,9 +62,9 @@ -
  • | Last Published: 2015-05-13
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -143,7 +143,7 @@ - +
  • @@ -197,9 +197,23 @@ Nuspec Analyzer
  • + +
  • + + + + Autoconf Analyzer +
  • + +
  • + + + + OpenSSL Analyzer +
  • - +
  • diff --git a/analyzers/nuspec-analyzer.html b/analyzers/nuspec-analyzer.html index c04530652..277c1732d 100644 --- a/analyzers/nuspec-analyzer.html +++ b/analyzers/nuspec-analyzer.html @@ -1,13 +1,13 @@ - + dependency-check - Nuspec Analyzer @@ -62,9 +62,9 @@ -
  • | Last Published: 2015-05-13
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -143,7 +143,7 @@ - +
  • @@ -197,9 +197,23 @@ Nuspec Analyzer
  • + +
  • + + + + Autoconf Analyzer +
  • + +
  • + + + + OpenSSL Analyzer +
  • - +
  • diff --git a/analyzers/openssl-analyzer.html b/analyzers/openssl-analyzer.html new file mode 100644 index 000000000..9a6c23942 --- /dev/null +++ b/analyzers/openssl-analyzer.html @@ -0,0 +1,297 @@ + + + + + + + + + dependency-check - OpenSSL Analyzer + + + + + + + + + + + + + + + + + + + + + Fork me on GitHub + + + + + +
    + + + + + +
    +
    + +
    + + +
    + +

    OpenSSL Analyzer

    +

    OWASP dependency-check includes an analyzer that will scan OpenSSL source code files for the OpenSSL version information. 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: opensslv.h

    +
    +
    +
    + +
    + +
    +
    +
    +

    Copyright © 2012–2015 + OWASP. + All rights reserved. + +

    +
    + + + +
    +
    + + diff --git a/analyzers/python-analyzer.html b/analyzers/python-analyzer.html index 8f600b243..5f86ca7f7 100644 --- a/analyzers/python-analyzer.html +++ b/analyzers/python-analyzer.html @@ -1,13 +1,13 @@ - + dependency-check - Python Analyzer @@ -62,9 +62,9 @@ -
  • | Last Published: 2015-05-13
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -143,14 +143,77 @@ - +
  • - + File Type Analyzers -
  • - + + +
  • diff --git a/current.txt b/current.txt index bb7a48bb9..589268e6f 100644 --- a/current.txt +++ b/current.txt @@ -1 +1 @@ -1.2.11 \ No newline at end of file +1.3.0 \ No newline at end of file diff --git a/data/database.html b/data/database.html index b3d8e771c..99fc5be4d 100644 --- a/data/database.html +++ b/data/database.html @@ -1,13 +1,13 @@ - + dependency-check - Using a Database Server @@ -62,9 +62,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -164,14 +164,14 @@ - +
  • File Type Analyzers
  • - +
  • diff --git a/data/index.html b/data/index.html index a9ea09afe..ca995b41e 100644 --- a/data/index.html +++ b/data/index.html @@ -1,13 +1,13 @@ - + dependency-check - Internet Access Required @@ -62,9 +62,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -164,14 +164,14 @@ - +
  • File Type Analyzers
  • - +
  • diff --git a/data/mirrornvd.html b/data/mirrornvd.html index 4cd7ee7f3..c84b19c41 100644 --- a/data/mirrornvd.html +++ b/data/mirrornvd.html @@ -1,13 +1,13 @@ - + dependency-check - Mirroring the NVD from NIST @@ -62,9 +62,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -164,14 +164,14 @@ - +
  • File Type Analyzers
  • - +
  • diff --git a/data/proxy.html b/data/proxy.html index d921a4f66..9c1f75208 100644 --- a/data/proxy.html +++ b/data/proxy.html @@ -1,13 +1,13 @@ - + dependency-check - Proxy Configuration @@ -62,9 +62,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -164,14 +164,14 @@ - +
  • File Type Analyzers
  • - +
  • diff --git a/dependency-check-ant/apidocs/allclasses-frame.html b/dependency-check-ant/apidocs/allclasses-frame.html index 33d523851..2f993456b 100644 --- a/dependency-check-ant/apidocs/allclasses-frame.html +++ b/dependency-check-ant/apidocs/allclasses-frame.html @@ -2,18 +2,21 @@ - + -All Classes (Dependency-Check Ant Task 1.2.11 API) - +All Classes (Dependency-Check Ant Task 1.3.0 API) +

    All Classes

    diff --git a/dependency-check-ant/apidocs/allclasses-noframe.html b/dependency-check-ant/apidocs/allclasses-noframe.html index 180e37469..f8bdc1ea2 100644 --- a/dependency-check-ant/apidocs/allclasses-noframe.html +++ b/dependency-check-ant/apidocs/allclasses-noframe.html @@ -2,18 +2,21 @@ - + -All Classes (Dependency-Check Ant Task 1.2.11 API) - +All Classes (Dependency-Check Ant Task 1.3.0 API) +

    All Classes

    diff --git a/dependency-check-ant/apidocs/constant-values.html b/dependency-check-ant/apidocs/constant-values.html index 989916c74..5be92a0e5 100644 --- a/dependency-check-ant/apidocs/constant-values.html +++ b/dependency-check-ant/apidocs/constant-values.html @@ -2,16 +2,16 @@ - + -Constant Field Values (Dependency-Check Ant Task 1.2.11 API) - +Constant Field Values (Dependency-Check Ant Task 1.3.0 API) + @@ -25,10 +25,11 @@ @@ -164,7 +164,7 @@

    About

    OWASP dependency-check-ant is an Ant Task that uses dependency-check-core to detect publicly disclosed vulnerabilities associated with the project’s dependencies. The task will generate a report listing the dependency, any identified Common Platform Enumeration (CPE) identifiers, and the associated Common Vulnerability and Exposure (CVE) entries.

    Installation

    -

    Download dependency-check-ant from bintray here. To install dependency-check-ant place the dependency-check-ant-1.2.11.jar into the lib directory of your Ant instalation directory. Once installed you can add the taskdef to you build.xml and add the task to a new or existing target:

    +

    Download dependency-check-ant from bintray here. To install dependency-check-ant place the dependency-check-ant-1.3.0.jar into the lib directory of your Ant instalation directory. Once installed you can add the taskdef to you build.xml and add the task to a new or existing target:

    <taskdef name="dependency-check" classname="org.owasp.dependencycheck.taskdefs.DependencyCheckTask"/>
    @@ -173,7 +173,7 @@
     
     
    <taskdef name="dependency-check" classname="org.owasp.dependencycheck.taskdefs.DependencyCheckTask">
    -    <classpath path="[path]/[to]/dependency-check-ant-1.2.11.jar"/>
    +    <classpath path="[path]/[to]/dependency-check-ant-1.3.0.jar"/>
     </taskdef>
     

    It is important to understand that the first time this task is executed it may take 10 minutes or more as it downloads and processes the data from the National Vulnerability Database (NVD) hosted by NIST: https://nvd.nist.gov

    diff --git a/dependency-check-ant/issue-tracking.html b/dependency-check-ant/issue-tracking.html index 956dfbc22..a1f3e2be4 100644 --- a/dependency-check-ant/issue-tracking.html +++ b/dependency-check-ant/issue-tracking.html @@ -1,13 +1,13 @@ - + dependency-check-ant - Issue Tracking @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • diff --git a/dependency-check-ant/license.html b/dependency-check-ant/license.html index a986455bf..441c01a7b 100644 --- a/dependency-check-ant/license.html +++ b/dependency-check-ant/license.html @@ -1,13 +1,13 @@ - + dependency-check-ant - Project License @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • diff --git a/dependency-check-ant/mail-lists.html b/dependency-check-ant/mail-lists.html index d3814e1dd..db423f088 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 @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • diff --git a/dependency-check-ant/plugin-updates-report.html b/dependency-check-ant/plugin-updates-report.html index a4cf59e0f..1b7cf0c4f 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 @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -252,7 +252,7 @@ # of plugins using the latest version available -13 +16 # of plugins where the next version available is smaller than an incremental version update @@ -264,7 +264,7 @@ # of plugins where the next version available is a minor version update -6 +3 # of plugins where the next version available is a major version update @@ -287,20 +287,20 @@ Next Major Dependency status - + org.apache.maven.plugins maven-antrun-plugin -1.3 +1.8 + -1.4 org.apache.maven.plugins maven-assembly-plugin -2.5.3 +2.5.5 @@ -320,21 +320,21 @@ org.apache.maven.plugins maven-compiler-plugin -3.2 +3.3 - + org.apache.maven.plugins maven-dependency-plugin -2.9 - - 2.10 + + + @@ -367,14 +367,14 @@ - + org.apache.maven.plugins maven-gpg-plugin -1.5 - - 1.6 + + + @@ -390,7 +390,7 @@ org.apache.maven.plugins maven-jar-plugin -2.5 +2.6 @@ -400,17 +400,17 @@ org.apache.maven.plugins maven-plugin-plugin -3.3 +3.2 -3.4 +3.3 org.apache.maven.plugins maven-release-plugin -2.5.1 +2.5.2 @@ -450,7 +450,7 @@ org.codehaus.mojo appassembler-maven-plugin -1.9 +1.10 @@ -460,7 +460,7 @@ org.codehaus.mojo cobertura-maven-plugin -2.6 +2.7 @@ -517,7 +517,7 @@ - + @@ -526,10 +526,7 @@ - - - -
    Status There is at least one newer minor version available. Minor updates are sometimes passive.
     No newer versions available.
    Group Id org.apache.maven.plugins
    maven-antrun-plugin
    Current Version1.3
    Newer versions1.4 Next Minor
    1.5
    1.6
    1.7
    1.8 Latest Minor
    +1.8

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

    @@ -544,7 +541,7 @@ -
    maven-assembly-plugin
    Current Version2.5.3
    +2.5.5

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

    @@ -574,13 +571,13 @@ -
    maven-compiler-plugin
    Current Version3.2
    +3.3

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

    - + @@ -589,10 +586,7 @@ - - - -
    Status There is at least one newer minor version available. Minor updates are sometimes passive.
     No newer versions available.
    Group Id org.apache.maven.plugins
    maven-dependency-plugin
    Current Version2.9
    Newer versions2.10 Next Minor
    +2.10

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

    @@ -646,7 +640,7 @@
    - + @@ -655,10 +649,7 @@ - - - -
    Status There is at least one newer minor version available. Minor updates are sometimes passive.
     No newer versions available.
    Group Id org.apache.maven.plugins
    maven-gpg-plugin
    Current Version1.5
    Newer versions1.6 Next Minor
    +1.6

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

    @@ -688,7 +679,7 @@ -
    maven-jar-plugin
    Current Version2.5
    +2.6

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

    @@ -703,10 +694,10 @@ - + -
    maven-plugin-plugin
    Current Version3.3
    3.2
    Newer versions3.4 Next Minor
    +3.3 Next Minor
    3.4 Latest Minor

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

    @@ -721,7 +712,7 @@ -
    maven-release-plugin
    Current Version2.5.1
    +2.5.2

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

    @@ -799,7 +790,7 @@ -
    appassembler-maven-plugin
    Current Version1.9
    +1.10

    Plugin org.codehaus.mojo:cobertura-maven-plugin

    @@ -814,7 +805,7 @@ -
    cobertura-maven-plugin
    Current Version2.6
    +2.7 diff --git a/dependency-check-ant/pmd.html b/dependency-check-ant/pmd.html index 1db38cab7..90d1c89d0 100644 --- a/dependency-check-ant/pmd.html +++ b/dependency-check-ant/pmd.html @@ -1,13 +1,13 @@ - + dependency-check-ant - PMD Results @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • diff --git a/dependency-check-ant/project-info.html b/dependency-check-ant/project-info.html index ca3c919db..0cf03bba4 100644 --- a/dependency-check-ant/project-info.html +++ b/dependency-check-ant/project-info.html @@ -1,13 +1,13 @@ - + dependency-check-ant - Project Information @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • diff --git a/dependency-check-ant/project-reports.html b/dependency-check-ant/project-reports.html index 0745d4241..a913c8750 100644 --- a/dependency-check-ant/project-reports.html +++ b/dependency-check-ant/project-reports.html @@ -1,13 +1,13 @@ - + dependency-check-ant - Generated Reports @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • diff --git a/dependency-check-ant/project-summary.html b/dependency-check-ant/project-summary.html index f113c89c8..3aca9f9c2 100644 --- a/dependency-check-ant/project-summary.html +++ b/dependency-check-ant/project-summary.html @@ -1,13 +1,13 @@ - + dependency-check-ant - Project Summary @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -246,7 +246,7 @@ dependency-check-ant Version -1.2.11 +1.3.0 Type jar diff --git a/dependency-check-ant/source-repository.html b/dependency-check-ant/source-repository.html index 99843f6a1..8eebb6487 100644 --- a/dependency-check-ant/source-repository.html +++ b/dependency-check-ant/source-repository.html @@ -1,13 +1,13 @@ - + dependency-check-ant - Source Repository @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • diff --git a/dependency-check-ant/surefire-report.html b/dependency-check-ant/surefire-report.html index f1c6837e3..b7c5a5943 100644 --- a/dependency-check-ant/surefire-report.html +++ b/dependency-check-ant/surefire-report.html @@ -1,13 +1,13 @@ - + dependency-check-ant - Surefire Report @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -281,7 +281,7 @@ function toggleDisplay(elementId) { 0 0 100% -16.009
    +17.063

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


    Package List

    @@ -302,7 +302,7 @@ function toggleDisplay(elementId) { 0 0 100% -16.009
    +17.063

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

    org.owasp.dependencycheck.taskdefs

    @@ -324,7 +324,7 @@ function toggleDisplay(elementId) { 0 0 100% -16.009

    +17.063

    Test Cases

    [Summary] [Package List] [Test Cases]

    @@ -334,19 +334,19 @@ function toggleDisplay(elementId) { testGetFailBuildOnCVSS -0.461 +0.574 testAddDirSet -7.53 +7.874 testAddFileSet -4.351 +4.733 testAddFileList -3.667

    +3.882
    diff --git a/dependency-check-ant/taglist.html b/dependency-check-ant/taglist.html index 69e340dcc..f95520978 100644 --- a/dependency-check-ant/taglist.html +++ b/dependency-check-ant/taglist.html @@ -1,13 +1,13 @@ - + dependency-check-ant - Tag List report @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -255,25 +255,19 @@ Tag strings used by tag class Todo Work -2 +1 todo, FIXME

    Each tag is detailed below:

    Todo Work

    -

    Number of occurrences found in the code: 2

    +

    Number of occurrences found in the code: 1

    - - - - - - -
    org.owasp.dependencycheck.taskdefs.DependencyCheckTask Line
    - should this be its own task?938
    org.owasp.dependencycheck.taskdefs.DependencyCheckTaskTestLine
    The use of deprecated class BuildFileTestcan possibly be replaced with BuildFileRule. However, it currently isn't included in the ant-testutil jar. This should be fixed in ant-testutil 1.9.5, so we can check back once that has been released. Reference: http://mail-archives.apache.org/mod_mbox/ant-user/201406.mbox/%3C000001cf87ba$8949b690$9bdd23b0$@de%3E33
    +907 diff --git a/dependency-check-ant/team-list.html b/dependency-check-ant/team-list.html index 96de0c1c9..a47e6a24b 100644 --- a/dependency-check-ant/team-list.html +++ b/dependency-check-ant/team-list.html @@ -1,13 +1,13 @@ - + dependency-check-ant - Team list @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -238,6 +238,13 @@ Will.Stranathan@owasp.org OWASP https://www.owasp.org/ +developer + + +Dale Visser +dvisser@ida.org +Institute for Defense Analyses +https://www.ida.org/ developer

    Contributors

    diff --git a/dependency-check-ant/usage.html b/dependency-check-ant/usage.html index f4d8b80aa..92c18f77c 100644 --- a/dependency-check-ant/usage.html +++ b/dependency-check-ant/usage.html @@ -1,13 +1,13 @@ - + dependency-check-ant - Usage @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -169,7 +169,7 @@
    <taskdef name="dependency-check" classname="org.owasp.dependencycheck.taskdefs.DependencyCheckTask">
    -    <classpath path="[path]/[to]/dependency-check-ant-1.2.11.jar"/>
    +    <classpath path="[path]/[to]/dependency-check-ant-1.3.0.jar"/>
     </taskdef>
     

    Next, add the task to a target of your choosing:

    diff --git a/dependency-check-ant/xref-test/index.html b/dependency-check-ant/xref-test/index.html index 4925268b0..2f21e70fd 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.2.11 Reference + Dependency-Check Ant Task 1.3.0 Reference diff --git a/dependency-check-ant/xref-test/org/owasp/dependencycheck/taskdefs/DependencyCheckTaskTest.html b/dependency-check-ant/xref-test/org/owasp/dependencycheck/taskdefs/DependencyCheckTaskTest.html index 02e4b856e..2af1a2044 100644 --- a/dependency-check-ant/xref-test/org/owasp/dependencycheck/taskdefs/DependencyCheckTaskTest.html +++ b/dependency-check-ant/xref-test/org/owasp/dependencycheck/taskdefs/DependencyCheckTaskTest.html @@ -26,101 +26,108 @@ 18 package org.owasp.dependencycheck.taskdefs; 19 20 import java.io.File; -21 import org.apache.tools.ant.BuildFileTest; -22 import org.junit.After; -23 import org.junit.Before; -24 import org.junit.Test; -25 import org.owasp.dependencycheck.data.nvdcve.BaseDBTestCase; -26 import org.owasp.dependencycheck.utils.Settings; -27 -28 /** -29 * -30 * @author Jeremy Long -31 */ -32 public class DependencyCheckTaskTest extends BuildFileTest { -33 //TODO: The use of deprecated class BuildFileTestcan possibly -34 //be replaced with BuildFileRule. However, it currently isn't included in the ant-testutil jar. -35 //This should be fixed in ant-testutil 1.9.5, so we can check back once that has been released. -36 //Reference: http://mail-archives.apache.org/mod_mbox/ant-user/201406.mbox/%3C000001cf87ba$8949b690$9bdd23b0$@de%3E -37 -38 @Before -39 @Override -40 public void setUp() throws Exception { -41 Settings.initialize(); -42 BaseDBTestCase.ensureDBExists(); -43 final String buildFile = this.getClass().getClassLoader().getResource("build.xml").getPath(); -44 configureProject(buildFile); -45 } +21 +22 import org.apache.tools.ant.BuildException; +23 import org.apache.tools.ant.BuildFileRule; +24 import org.junit.After; +25 import org.junit.Before; +26 import org.junit.Rule; +27 import org.junit.Test; +28 import org.junit.rules.ExpectedException; +29 import org.owasp.dependencycheck.data.nvdcve.BaseDBTestCase; +30 import org.owasp.dependencycheck.utils.Settings; +31 +32 import static org.junit.Assert.assertTrue; +33 +34 +35 /** +36 * +37 * @author Jeremy Long +38 */ +39 public class DependencyCheckTaskTest { +40 +41 @Rule +42 public BuildFileRule buildFileRule = new BuildFileRule(); +43 +44 @Rule +45 public ExpectedException expectedException = ExpectedException.none(); 46 -47 @After -48 @Override -49 public void tearDown() { -50 //no cleanup... -51 //executeTarget("cleanup"); -52 Settings.cleanup(true); +47 @Before +48 public void setUp() throws Exception { +49 Settings.initialize(); +50 BaseDBTestCase.ensureDBExists(); +51 final String buildFile = this.getClass().getClassLoader().getResource("build.xml").getPath(); +52 buildFileRule.configureProject(buildFile); 53 } 54 -55 /** -56 * Test of addFileSet method, of class DependencyCheckTask. -57 */ -58 @Test -59 public void testAddFileSet() throws Exception { -60 File report = new File("target/dependency-check-report.html"); -61 if (report.exists()) { -62 if (!report.delete()) { -63 throw new Exception("Unable to delete 'target/DependencyCheck-Report.html' prior to test."); -64 } -65 } -66 executeTarget("test.fileset"); -67 -68 assertTrue("DependencyCheck report was not generated", report.exists()); -69 -70 } -71 -72 /** -73 * Test of addFileList method, of class DependencyCheckTask. -74 * -75 * @throws Exception -76 */ -77 @Test -78 public void testAddFileList() throws Exception { -79 File report = new File("target/dependency-check-report.xml"); -80 if (report.exists()) { -81 if (!report.delete()) { -82 throw new Exception("Unable to delete 'target/DependencyCheck-Report.xml' prior to test."); -83 } -84 } -85 executeTarget("test.filelist"); -86 -87 assertTrue("DependencyCheck report was not generated", report.exists()); -88 } -89 -90 /** -91 * Test of addDirSet method, of class DependencyCheckTask. -92 * -93 * @throws Exception -94 */ -95 @Test -96 public void testAddDirSet() throws Exception { -97 File report = new File("target/dependency-check-vulnerability.html"); -98 if (report.exists()) { -99 if (!report.delete()) { -100 throw new Exception("Unable to delete 'target/DependencyCheck-Vulnerability.html' prior to test."); -101 } -102 } -103 executeTarget("test.dirset"); -104 assertTrue("DependencyCheck report was not generated", report.exists()); -105 } -106 -107 /** -108 * Test of getFailBuildOnCVSS method, of class DependencyCheckTask. -109 */ -110 @Test -111 public void testGetFailBuildOnCVSS() { -112 expectBuildException("failCVSS", "asdfasdfscore"); -113 System.out.println(this.getOutput()); -114 } -115 } +55 @After +56 public void tearDown() { +57 //no cleanup... +58 //executeTarget("cleanup"); +59 Settings.cleanup(true); +60 } +61 +62 /** +63 * Test of addFileSet method, of class DependencyCheckTask. +64 */ +65 @Test +66 public void testAddFileSet() throws Exception { +67 File report = new File("target/dependency-check-report.html"); +68 if (report.exists()) { +69 if (!report.delete()) { +70 throw new Exception("Unable to delete 'target/DependencyCheck-Report.html' prior to test."); +71 } +72 } +73 buildFileRule.executeTarget("test.fileset"); +74 +75 assertTrue("DependencyCheck report was not generated", report.exists()); +76 +77 } +78 +79 /** +80 * Test of addFileList method, of class DependencyCheckTask. +81 * +82 * @throws Exception +83 */ +84 @Test +85 public void testAddFileList() throws Exception { +86 File report = new File("target/dependency-check-report.xml"); +87 if (report.exists()) { +88 if (!report.delete()) { +89 throw new Exception("Unable to delete 'target/DependencyCheck-Report.xml' prior to test."); +90 } +91 } +92 buildFileRule.executeTarget("test.filelist"); +93 +94 assertTrue("DependencyCheck report was not generated", report.exists()); +95 } +96 +97 /** +98 * Test of addDirSet method, of class DependencyCheckTask. +99 * +100 * @throws Exception +101 */ +102 @Test +103 public void testAddDirSet() throws Exception { +104 File report = new File("target/dependency-check-vulnerability.html"); +105 if (report.exists()) { +106 if (!report.delete()) { +107 throw new Exception("Unable to delete 'target/DependencyCheck-Vulnerability.html' prior to test."); +108 } +109 } +110 buildFileRule.executeTarget("test.dirset"); +111 assertTrue("DependencyCheck report was not generated", report.exists()); +112 } +113 +114 /** +115 * Test of getFailBuildOnCVSS method, of class DependencyCheckTask. +116 */ +117 @Test +118 public void testGetFailBuildOnCVSS() { +119 expectedException.expect(BuildException.class); +120 buildFileRule.executeTarget("failCVSS"); +121 } +122 }
    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 9aa701120..e7c09372c 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.2.11 Reference Package org.owasp.dependencycheck.taskdefs + Dependency-Check Ant Task 1.3.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 26714f51f..d461154f2 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.2.11 Reference Package org.owasp.dependencycheck.taskdefs + Dependency-Check Ant Task 1.3.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 2bd616ad4..191597d53 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.2.11 Reference + Dependency-Check Ant Task 1.3.0 Reference diff --git a/dependency-check-ant/xref-test/overview-summary.html b/dependency-check-ant/xref-test/overview-summary.html index b3d2b39a3..6863db179 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.2.11 Reference + Dependency-Check Ant Task 1.3.0 Reference @@ -24,7 +24,7 @@
    -

    Dependency-Check Ant Task 1.2.11 Reference

    +

    Dependency-Check Ant Task 1.3.0 Reference

    diff --git a/dependency-check-ant/xref/allclasses-frame.html b/dependency-check-ant/xref/allclasses-frame.html index 340475148..7131a61a0 100644 --- a/dependency-check-ant/xref/allclasses-frame.html +++ b/dependency-check-ant/xref/allclasses-frame.html @@ -12,10 +12,19 @@ diff --git a/dependency-check-ant/xref/index.html b/dependency-check-ant/xref/index.html index 4925268b0..2f21e70fd 100644 --- a/dependency-check-ant/xref/index.html +++ b/dependency-check-ant/xref/index.html @@ -4,7 +4,7 @@ - Dependency-Check Ant Task 1.2.11 Reference + Dependency-Check Ant Task 1.3.0 Reference diff --git a/dependency-check-ant/xref/org/owasp/dependencycheck/ant/logging/AntLoggerAdapter.html b/dependency-check-ant/xref/org/owasp/dependencycheck/ant/logging/AntLoggerAdapter.html new file mode 100644 index 000000000..fbac1d909 --- /dev/null +++ b/dependency-check-ant/xref/org/owasp/dependencycheck/ant/logging/AntLoggerAdapter.html @@ -0,0 +1,284 @@ + + + +AntLoggerAdapter xref + + + +
    View Javadoc
    +1   /*
    +2    * This file is part of dependency-check-ant.
    +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) 2015 The OWASP Foundation. All Rights Reserved.
    +17   */
    +18  package org.owasp.dependencycheck.ant.logging;
    +19  
    +20  import org.apache.tools.ant.Project;
    +21  import org.apache.tools.ant.Task;
    +22  import org.slf4j.helpers.FormattingTuple;
    +23  import org.slf4j.helpers.MarkerIgnoringBase;
    +24  import org.slf4j.helpers.MessageFormatter;
    +25  
    +26  /**
    +27   * An instance of {@link org.slf4j.Logger} which simply calls the log method on the delegate Ant task
    +28   *
    +29   * @author colezlaw
    +30   */
    +31  public class AntLoggerAdapter extends MarkerIgnoringBase {
    +32  
    +33      /**
    +34       * A reference to the Ant task used for logging.
    +35       */
    +36      private Task task;
    +37  
    +38      /**
    +39       * Constructs an Ant Logger Adapter.
    +40       *
    +41       * @param task the Ant Task to use for logging
    +42       */
    +43      public AntLoggerAdapter(Task task) {
    +44          super();
    +45          this.task = task;
    +46      }
    +47  
    +48      /**
    +49       * Sets the current Ant task to use for logging.
    +50       *
    +51       * @param task the Ant task to use for logging
    +52       */
    +53      public void setTask(Task task) {
    +54          this.task = task;
    +55      }
    +56  
    +57      @Override
    +58      public boolean isTraceEnabled() {
    +59          // Might be a more efficient way to do this, but Ant doesn't enable or disable
    +60          // various levels globally - it just fires things at registered Listeners.
    +61          return true;
    +62      }
    +63  
    +64      @Override
    +65      public void trace(String msg) {
    +66          task.log(msg, Project.MSG_VERBOSE);
    +67      }
    +68  
    +69      @Override
    +70      public void trace(String format, Object arg) {
    +71          if (task != null) {
    +72              final FormattingTuple tp = MessageFormatter.format(format, arg);
    +73              task.log(tp.getMessage(), Project.MSG_VERBOSE);
    +74          }
    +75      }
    +76  
    +77      @Override
    +78      public void trace(String format, Object arg1, Object arg2) {
    +79          if (task != null) {
    +80              final FormattingTuple tp = MessageFormatter.format(format, arg1, arg2);
    +81              task.log(tp.getMessage(), Project.MSG_VERBOSE);
    +82          }
    +83      }
    +84  
    +85      @Override
    +86      public void trace(String format, Object... arguments) {
    +87          if (task != null) {
    +88              final FormattingTuple tp = MessageFormatter.format(format, arguments);
    +89              task.log(tp.getMessage(), Project.MSG_VERBOSE);
    +90          }
    +91      }
    +92  
    +93      @Override
    +94      public void trace(String msg, Throwable t) {
    +95          if (task != null) {
    +96              task.log(msg, t, Project.MSG_VERBOSE);
    +97          }
    +98      }
    +99  
    +100     @Override
    +101     public boolean isDebugEnabled() {
    +102         return true;
    +103     }
    +104 
    +105     @Override
    +106     public void debug(String msg) {
    +107         if (task != null) {
    +108             task.log(msg, Project.MSG_DEBUG);
    +109         }
    +110     }
    +111 
    +112     @Override
    +113     public void debug(String format, Object arg) {
    +114         if (task != null) {
    +115             final FormattingTuple tp = MessageFormatter.format(format, arg);
    +116             task.log(tp.getMessage(), Project.MSG_DEBUG);
    +117         }
    +118     }
    +119 
    +120     @Override
    +121     public void debug(String format, Object arg1, Object arg2) {
    +122         if (task != null) {
    +123             final FormattingTuple tp = MessageFormatter.format(format, arg1, arg2);
    +124             task.log(tp.getMessage(), Project.MSG_DEBUG);
    +125         }
    +126     }
    +127 
    +128     @Override
    +129     public void debug(String format, Object... arguments) {
    +130         if (task != null) {
    +131             final FormattingTuple tp = MessageFormatter.format(format, arguments);
    +132             task.log(tp.getMessage(), Project.MSG_DEBUG);
    +133         }
    +134     }
    +135 
    +136     @Override
    +137     public void debug(String msg, Throwable t) {
    +138         if (task != null) {
    +139             task.log(msg, t, Project.MSG_DEBUG);
    +140         }
    +141     }
    +142 
    +143     @Override
    +144     public boolean isInfoEnabled() {
    +145         return true;
    +146     }
    +147 
    +148     @Override
    +149     public void info(String msg) {
    +150         if (task != null) {
    +151             task.log(msg, Project.MSG_INFO);
    +152         }
    +153     }
    +154 
    +155     @Override
    +156     public void info(String format, Object arg) {
    +157         if (task != null) {
    +158             final FormattingTuple tp = MessageFormatter.format(format, arg);
    +159             task.log(tp.getMessage(), Project.MSG_INFO);
    +160         }
    +161     }
    +162 
    +163     @Override
    +164     public void info(String format, Object arg1, Object arg2) {
    +165         if (task != null) {
    +166             final FormattingTuple tp = MessageFormatter.format(format, arg1, arg2);
    +167             task.log(tp.getMessage(), Project.MSG_INFO);
    +168         }
    +169     }
    +170 
    +171     @Override
    +172     public void info(String format, Object... arguments) {
    +173         if (task != null) {
    +174             final FormattingTuple tp = MessageFormatter.format(format, arguments);
    +175             task.log(tp.getMessage(), Project.MSG_INFO);
    +176         }
    +177     }
    +178 
    +179     @Override
    +180     public void info(String msg, Throwable t) {
    +181         if (task != null) {
    +182             task.log(msg, t, Project.MSG_INFO);
    +183         }
    +184     }
    +185 
    +186     @Override
    +187     public boolean isWarnEnabled() {
    +188         return true;
    +189     }
    +190 
    +191     @Override
    +192     public void warn(String msg) {
    +193         if (task != null) {
    +194             task.log(msg, Project.MSG_WARN);
    +195         }
    +196     }
    +197 
    +198     @Override
    +199     public void warn(String format, Object arg) {
    +200         if (task != null) {
    +201             final FormattingTuple tp = MessageFormatter.format(format, arg);
    +202             task.log(tp.getMessage(), Project.MSG_WARN);
    +203         }
    +204     }
    +205 
    +206     @Override
    +207     public void warn(String format, Object... arguments) {
    +208         if (task != null) {
    +209             final FormattingTuple tp = MessageFormatter.format(format, arguments);
    +210             task.log(tp.getMessage(), Project.MSG_WARN);
    +211         }
    +212     }
    +213 
    +214     @Override
    +215     public void warn(String format, Object arg1, Object arg2) {
    +216         if (task != null) {
    +217             final FormattingTuple tp = MessageFormatter.format(format, arg1, arg2);
    +218             task.log(tp.getMessage(), Project.MSG_WARN);
    +219         }
    +220     }
    +221 
    +222     @Override
    +223     public void warn(String msg, Throwable t) {
    +224         if (task != null) {
    +225             task.log(msg, t, Project.MSG_WARN);
    +226         }
    +227     }
    +228 
    +229     @Override
    +230     public boolean isErrorEnabled() {
    +231         return true;
    +232     }
    +233 
    +234     @Override
    +235     public void error(String msg) {
    +236         if (task != null) {
    +237             task.log(msg, Project.MSG_ERR);
    +238         }
    +239     }
    +240 
    +241     @Override
    +242     public void error(String format, Object arg) {
    +243         if (task != null) {
    +244             final FormattingTuple tp = MessageFormatter.format(format, arg);
    +245             task.log(tp.getMessage(), Project.MSG_ERR);
    +246         }
    +247     }
    +248 
    +249     @Override
    +250     public void error(String format, Object arg1, Object arg2) {
    +251         if (task != null) {
    +252             final FormattingTuple tp = MessageFormatter.format(format, arg1, arg2);
    +253             task.log(tp.getMessage(), Project.MSG_ERR);
    +254         }
    +255     }
    +256 
    +257     @Override
    +258     public void error(String format, Object... arguments) {
    +259         if (task != null) {
    +260             final FormattingTuple tp = MessageFormatter.format(format, arguments);
    +261             task.log(tp.getMessage(), Project.MSG_ERR);
    +262         }
    +263     }
    +264 
    +265     @Override
    +266     public void error(String msg, Throwable t) {
    +267         if (task != null) {
    +268             task.log(msg, t, Project.MSG_ERR);
    +269         }
    +270     }
    +271 }
    +
    +
    + + + diff --git a/dependency-check-ant/xref/org/owasp/dependencycheck/ant/logging/AntLoggerFactory.html b/dependency-check-ant/xref/org/owasp/dependencycheck/ant/logging/AntLoggerFactory.html new file mode 100644 index 000000000..4f7aeeb5c --- /dev/null +++ b/dependency-check-ant/xref/org/owasp/dependencycheck/ant/logging/AntLoggerFactory.html @@ -0,0 +1,69 @@ + + + +AntLoggerFactory xref + + + +
    View Javadoc
    +1   /*
    +2    * This file is part of dependency-check-ant.
    +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) 2015 The OWASP Foundation. All Rights Reserved.
    +17   */
    +18  package org.owasp.dependencycheck.ant.logging;
    +19  
    +20  import org.apache.tools.ant.Task;
    +21  import org.slf4j.ILoggerFactory;
    +22  import org.slf4j.Logger;
    +23  
    +24  /**
    +25   * An implementation of {@link org.slf4j.ILoggerFactory} which always returns {@link AntLoggerAdapter} instances.
    +26   *
    +27   * @author colezlaw
    +28   */
    +29  public class AntLoggerFactory implements ILoggerFactory {
    +30  
    +31      /**
    +32       * A reference to the Ant logger Adapter.
    +33       */
    +34      private final AntLoggerAdapter antLoggerAdapter;
    +35  
    +36      /**
    +37       * Constructs a new Ant Logger Factory.
    +38       *
    +39       * @param task the Ant task to use for logging
    +40       */
    +41      public AntLoggerFactory(Task task) {
    +42          super();
    +43          this.antLoggerAdapter = new AntLoggerAdapter(task);
    +44      }
    +45  
    +46      /**
    +47       * Returns the Ant logger adapter.
    +48       *
    +49       * @param name ignored in this implementation
    +50       * @return the Ant logger adapter
    +51       */
    +52      @Override
    +53      public Logger getLogger(String name) {
    +54          return antLoggerAdapter;
    +55      }
    +56  }
    +
    +
    + + + 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 new file mode 100644 index 000000000..505dfca44 --- /dev/null +++ b/dependency-check-ant/xref/org/owasp/dependencycheck/ant/logging/package-frame.html @@ -0,0 +1,27 @@ + + + + + + Dependency-Check Ant Task 1.3.0 Reference Package org.owasp.dependencycheck.ant.logging + + + + +

    + org.owasp.dependencycheck.ant.logging +

    + +

    Classes

    + + + + + \ No newline at end of file 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 new file mode 100644 index 000000000..45bc0efc2 --- /dev/null +++ b/dependency-check-ant/xref/org/owasp/dependencycheck/ant/logging/package-summary.html @@ -0,0 +1,74 @@ + + + + + + Dependency-Check Ant Task 1.3.0 Reference Package org.owasp.dependencycheck.ant.logging + + + +
    + +
    +
    + +
    + +

    Package org.owasp.dependencycheck.ant.logging

    + +
    + + + + + + + + + + + + + +
    Class Summary
    + AntLoggerAdapter +
    + AntLoggerFactory +
    + +
    + +
    +
    + +
    +
    + + + \ No newline at end of file diff --git a/dependency-check-ant/xref/org/owasp/dependencycheck/taskdefs/DependencyCheckTask.html b/dependency-check-ant/xref/org/owasp/dependencycheck/taskdefs/DependencyCheckTask.html index ac950f178..a051931eb 100644 --- a/dependency-check-ant/xref/org/owasp/dependencycheck/taskdefs/DependencyCheckTask.html +++ b/dependency-check-ant/xref/org/owasp/dependencycheck/taskdefs/DependencyCheckTask.html @@ -29,1201 +29,1168 @@ 21 import java.io.IOException; 22 import java.io.InputStream; 23 import java.util.List; -24 import java.util.logging.Level; -25 import java.util.logging.Logger; -26 import org.apache.tools.ant.BuildException; -27 import org.apache.tools.ant.Task; -28 import org.apache.tools.ant.types.EnumeratedAttribute; -29 import org.apache.tools.ant.types.Reference; -30 import org.apache.tools.ant.types.Resource; -31 import org.apache.tools.ant.types.ResourceCollection; -32 import org.apache.tools.ant.types.resources.FileProvider; -33 import org.apache.tools.ant.types.resources.Resources; -34 import org.owasp.dependencycheck.Engine; -35 import org.owasp.dependencycheck.data.nvdcve.CveDB; -36 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; -37 import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties; -38 import org.owasp.dependencycheck.dependency.Dependency; -39 import org.owasp.dependencycheck.dependency.Identifier; -40 import org.owasp.dependencycheck.dependency.Vulnerability; -41 import org.owasp.dependencycheck.reporting.ReportGenerator; -42 import org.owasp.dependencycheck.reporting.ReportGenerator.Format; -43 import org.owasp.dependencycheck.utils.LogUtils; -44 import org.owasp.dependencycheck.utils.Settings; -45 -46 /** -47 * An Ant task definition to execute dependency-check during an Ant build. -48 * -49 * @author Jeremy Long -50 */ -51 public class DependencyCheckTask extends Task { -52 -53 /** -54 * The properties file location. -55 */ -56 private static final String PROPERTIES_FILE = "task.properties"; -57 /** -58 * Name of the logging properties file. -59 */ -60 private static final String LOG_PROPERTIES_FILE = "log.properties"; +24 import org.apache.tools.ant.BuildException; +25 import org.apache.tools.ant.Project; +26 import org.apache.tools.ant.Task; +27 import org.apache.tools.ant.types.EnumeratedAttribute; +28 import org.apache.tools.ant.types.Reference; +29 import org.apache.tools.ant.types.Resource; +30 import org.apache.tools.ant.types.ResourceCollection; +31 import org.apache.tools.ant.types.resources.FileProvider; +32 import org.apache.tools.ant.types.resources.Resources; +33 import org.owasp.dependencycheck.Engine; +34 import org.owasp.dependencycheck.data.nvdcve.CveDB; +35 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; +36 import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties; +37 import org.owasp.dependencycheck.dependency.Dependency; +38 import org.owasp.dependencycheck.dependency.Identifier; +39 import org.owasp.dependencycheck.dependency.Vulnerability; +40 import org.owasp.dependencycheck.reporting.ReportGenerator; +41 import org.owasp.dependencycheck.reporting.ReportGenerator.Format; +42 import org.owasp.dependencycheck.utils.Settings; +43 import org.slf4j.impl.StaticLoggerBinder; +44 +45 /** +46 * An Ant task definition to execute dependency-check during an Ant build. +47 * +48 * @author Jeremy Long +49 */ +50 public class DependencyCheckTask extends Task { +51 +52 /** +53 * The properties file location. +54 */ +55 private static final String PROPERTIES_FILE = "task.properties"; +56 /** +57 * System specific new line character. +58 */ +59 private static final String NEW_LINE = System.getProperty("line.separator", "\n").intern(); +60 61 /** -62 * System specific new line character. +62 * Construct a new DependencyCheckTask. 63 */ -64 private static final String NEW_LINE = System.getProperty("line.separator", "\n").intern(); -65 /** -66 * The logger. -67 */ -68 private static final Logger LOGGER = Logger.getLogger(DependencyCheckTask.class.getName()); -69 -70 /** -71 * Construct a new DependencyCheckTask. -72 */ -73 public DependencyCheckTask() { -74 super(); -75 } -76 //The following code was copied Apache Ant PathConvert -77 //BEGIN COPY from org.apache.tools.ant.taskdefs.PathConvert -78 /** -79 * Path to be converted -80 */ -81 private Resources path = null; -82 /** -83 * Reference to path/fileset to convert -84 */ -85 private Reference refid = null; -86 -87 /** -88 * Add an arbitrary ResourceCollection. -89 * -90 * @param rc the ResourceCollection to add. -91 * @since Ant 1.7 -92 */ -93 public void add(ResourceCollection rc) { -94 if (isReference()) { -95 throw new BuildException("Nested elements are not allowed when using the refid attribute."); -96 } -97 getPath().add(rc); -98 } -99 -100 /** -101 * Returns the path. If the path has not been initialized yet, this class is synchronized, and will instantiate the path -102 * object. -103 * -104 * @return the path -105 */ -106 private synchronized Resources getPath() { -107 if (path == null) { -108 path = new Resources(getProject()); -109 path.setCache(true); -110 } -111 return path; -112 } -113 -114 /** -115 * Learn whether the refid attribute of this element been set. -116 * -117 * @return true if refid is valid. -118 */ -119 public boolean isReference() { -120 return refid != null; -121 } -122 -123 /** -124 * Add a reference to a Path, FileSet, DirSet, or FileList defined elsewhere. -125 * -126 * @param r the reference to a path, fileset, dirset or filelist. -127 */ -128 public void setRefid(Reference r) { -129 if (path != null) { -130 throw new BuildException("Nested elements are not allowed when using the refid attribute."); -131 } -132 refid = r; -133 } -134 -135 /** -136 * If this is a reference, this method will add the referenced resource collection to the collection of paths. -137 * -138 * @throws BuildException if the reference is not to a resource collection -139 */ -140 private void dealWithReferences() throws BuildException { -141 if (isReference()) { -142 final Object o = refid.getReferencedObject(getProject()); -143 if (!(o instanceof ResourceCollection)) { -144 throw new BuildException("refid '" + refid.getRefId() -145 + "' does not refer to a resource collection."); -146 } -147 getPath().add((ResourceCollection) o); -148 } -149 } -150 // END COPY from org.apache.tools.ant.taskdefs -151 /** -152 * The application name for the report. -153 */ -154 private String applicationName = "Dependency-Check"; -155 -156 /** -157 * Get the value of applicationName. -158 * -159 * @return the value of applicationName -160 */ -161 public String getApplicationName() { -162 return applicationName; -163 } -164 -165 /** -166 * Set the value of applicationName. -167 * -168 * @param applicationName new value of applicationName +64 public DependencyCheckTask() { +65 super(); +66 // Call this before Dependency Check Core starts logging anything - this way, all SLF4J messages from +67 // core end up coming through this tasks logger +68 StaticLoggerBinder.getSingleton().setTask(this); +69 } +70 //The following code was copied Apache Ant PathConvert +71 //BEGIN COPY from org.apache.tools.ant.taskdefs.PathConvert +72 /** +73 * Path to be converted +74 */ +75 private Resources path = null; +76 /** +77 * Reference to path/fileset to convert +78 */ +79 private Reference refid = null; +80 +81 /** +82 * Add an arbitrary ResourceCollection. +83 * +84 * @param rc the ResourceCollection to add. +85 * @since Ant 1.7 +86 */ +87 public void add(ResourceCollection rc) { +88 if (isReference()) { +89 throw new BuildException("Nested elements are not allowed when using the refid attribute."); +90 } +91 getPath().add(rc); +92 } +93 +94 /** +95 * Returns the path. If the path has not been initialized yet, this class is synchronized, and will instantiate the path +96 * object. +97 * +98 * @return the path +99 */ +100 private synchronized Resources getPath() { +101 if (path == null) { +102 path = new Resources(getProject()); +103 path.setCache(true); +104 } +105 return path; +106 } +107 +108 /** +109 * Learn whether the refid attribute of this element been set. +110 * +111 * @return true if refid is valid. +112 */ +113 public boolean isReference() { +114 return refid != null; +115 } +116 +117 /** +118 * Add a reference to a Path, FileSet, DirSet, or FileList defined elsewhere. +119 * +120 * @param r the reference to a path, fileset, dirset or filelist. +121 */ +122 public void setRefid(Reference r) { +123 if (path != null) { +124 throw new BuildException("Nested elements are not allowed when using the refid attribute."); +125 } +126 refid = r; +127 } +128 +129 /** +130 * If this is a reference, this method will add the referenced resource collection to the collection of paths. +131 * +132 * @throws BuildException if the reference is not to a resource collection +133 */ +134 private void dealWithReferences() throws BuildException { +135 if (isReference()) { +136 final Object o = refid.getReferencedObject(getProject()); +137 if (!(o instanceof ResourceCollection)) { +138 throw new BuildException("refid '" + refid.getRefId() +139 + "' does not refer to a resource collection."); +140 } +141 getPath().add((ResourceCollection) o); +142 } +143 } +144 // END COPY from org.apache.tools.ant.taskdefs +145 /** +146 * The application name for the report. +147 */ +148 private String applicationName = "Dependency-Check"; +149 +150 /** +151 * Get the value of applicationName. +152 * +153 * @return the value of applicationName +154 */ +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 */ +164 public void setApplicationName(String applicationName) { +165 this.applicationName = applicationName; +166 } +167 /** +168 * The location of the data directory that contains 169 */ -170 public void setApplicationName(String applicationName) { -171 this.applicationName = applicationName; -172 } -173 /** -174 * The location of the data directory that contains -175 */ -176 private String dataDirectory = null; -177 -178 /** -179 * Get the value of dataDirectory. -180 * -181 * @return the value of dataDirectory -182 */ -183 public String getDataDirectory() { -184 return dataDirectory; -185 } -186 -187 /** -188 * Set the value of dataDirectory. -189 * -190 * @param dataDirectory new value of dataDirectory +170 private String dataDirectory = null; +171 +172 /** +173 * Get the value of dataDirectory. +174 * +175 * @return the value of dataDirectory +176 */ +177 public String getDataDirectory() { +178 return dataDirectory; +179 } +180 +181 /** +182 * Set the value of dataDirectory. +183 * +184 * @param dataDirectory new value of dataDirectory +185 */ +186 public void setDataDirectory(String dataDirectory) { +187 this.dataDirectory = dataDirectory; +188 } +189 /** +190 * Specifies the destination directory for the generated Dependency-Check report. 191 */ -192 public void setDataDirectory(String dataDirectory) { -193 this.dataDirectory = dataDirectory; -194 } -195 /** -196 * Specifies the destination directory for the generated Dependency-Check report. -197 */ -198 private String reportOutputDirectory = "."; -199 -200 /** -201 * Get the value of reportOutputDirectory. -202 * -203 * @return the value of reportOutputDirectory -204 */ -205 public String getReportOutputDirectory() { -206 return reportOutputDirectory; -207 } -208 -209 /** -210 * Set the value of reportOutputDirectory. -211 * -212 * @param reportOutputDirectory new value of reportOutputDirectory -213 */ -214 public void setReportOutputDirectory(String reportOutputDirectory) { -215 this.reportOutputDirectory = reportOutputDirectory; -216 } -217 /** -218 * Specifies if the build should be failed if a CVSS score above a specified level is identified. The default is 11 which -219 * 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 -220 * for the fail build on CVSS is 0 to 11, where anything above 10 will not cause the build to fail. -221 */ -222 private float failBuildOnCVSS = 11; -223 -224 /** -225 * Get the value of failBuildOnCVSS. -226 * -227 * @return the value of failBuildOnCVSS -228 */ -229 public float getFailBuildOnCVSS() { -230 return failBuildOnCVSS; -231 } -232 -233 /** -234 * Set the value of failBuildOnCVSS. -235 * -236 * @param failBuildOnCVSS new value of failBuildOnCVSS -237 */ -238 public void setFailBuildOnCVSS(float failBuildOnCVSS) { -239 this.failBuildOnCVSS = failBuildOnCVSS; -240 } +192 private String reportOutputDirectory = "."; +193 +194 /** +195 * Get the value of reportOutputDirectory. +196 * +197 * @return the value of reportOutputDirectory +198 */ +199 public String getReportOutputDirectory() { +200 return reportOutputDirectory; +201 } +202 +203 /** +204 * Set the value of reportOutputDirectory. +205 * +206 * @param reportOutputDirectory new value of reportOutputDirectory +207 */ +208 public void setReportOutputDirectory(String reportOutputDirectory) { +209 this.reportOutputDirectory = reportOutputDirectory; +210 } +211 /** +212 * Specifies if the build should be failed if a CVSS score above a specified level is identified. The default is 11 which +213 * 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 +214 * for the fail build on CVSS is 0 to 11, where anything above 10 will not cause the build to fail. +215 */ +216 private float failBuildOnCVSS = 11; +217 +218 /** +219 * Get the value of failBuildOnCVSS. +220 * +221 * @return the value of failBuildOnCVSS +222 */ +223 public float getFailBuildOnCVSS() { +224 return failBuildOnCVSS; +225 } +226 +227 /** +228 * Set the value of failBuildOnCVSS. +229 * +230 * @param failBuildOnCVSS new value of failBuildOnCVSS +231 */ +232 public void setFailBuildOnCVSS(float failBuildOnCVSS) { +233 this.failBuildOnCVSS = failBuildOnCVSS; +234 } +235 /** +236 * Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not recommended that this be turned to false. Default +237 * is true. +238 */ +239 private boolean autoUpdate = true; +240 241 /** -242 * Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not recommended that this be turned to false. Default -243 * is true. -244 */ -245 private boolean autoUpdate = true; -246 -247 /** -248 * Get the value of autoUpdate. -249 * -250 * @return the value of autoUpdate -251 */ -252 public boolean isAutoUpdate() { -253 return autoUpdate; -254 } -255 -256 /** -257 * Set the value of autoUpdate. -258 * -259 * @param autoUpdate new value of autoUpdate +242 * Get the value of autoUpdate. +243 * +244 * @return the value of autoUpdate +245 */ +246 public boolean isAutoUpdate() { +247 return autoUpdate; +248 } +249 +250 /** +251 * Set the value of autoUpdate. +252 * +253 * @param autoUpdate new value of autoUpdate +254 */ +255 public void setAutoUpdate(boolean autoUpdate) { +256 this.autoUpdate = autoUpdate; +257 } +258 /** +259 * Whether only the update phase should be executed. 260 */ -261 public void setAutoUpdate(boolean autoUpdate) { -262 this.autoUpdate = autoUpdate; -263 } -264 /** -265 * Whether only the update phase should be executed. -266 */ -267 private boolean updateOnly = false; -268 -269 /** -270 * Get the value of updateOnly. -271 * -272 * @return the value of updateOnly -273 */ -274 public boolean isUpdateOnly() { -275 return updateOnly; -276 } -277 -278 /** -279 * Set the value of updateOnly. -280 * -281 * @param updateOnly new value of updateOnly -282 */ -283 public void setUpdateOnly(boolean updateOnly) { -284 this.updateOnly = updateOnly; -285 } +261 private boolean updateOnly = false; +262 +263 /** +264 * Get the value of updateOnly. +265 * +266 * @return the value of updateOnly +267 */ +268 public boolean isUpdateOnly() { +269 return updateOnly; +270 } +271 +272 /** +273 * Set the value of updateOnly. +274 * +275 * @param updateOnly new value of updateOnly +276 */ +277 public void setUpdateOnly(boolean updateOnly) { +278 this.updateOnly = updateOnly; +279 } +280 +281 /** +282 * The report format to be generated (HTML, XML, VULN, ALL). This configuration option has no affect if using this within the +283 * Site plugin unless the externalReport is set to true. Default is HTML. +284 */ +285 private String reportFormat = "HTML"; 286 287 /** -288 * The report format to be generated (HTML, XML, VULN, ALL). This configuration option has no affect if using this within the -289 * Site plugin unless the externalReport is set to true. Default is HTML. -290 */ -291 private String reportFormat = "HTML"; -292 -293 /** -294 * Get the value of reportFormat. -295 * -296 * @return the value of reportFormat -297 */ -298 public String getReportFormat() { -299 return reportFormat; -300 } -301 -302 /** -303 * Set the value of reportFormat. -304 * -305 * @param reportFormat new value of reportFormat +288 * Get the value of reportFormat. +289 * +290 * @return the value of reportFormat +291 */ +292 public String getReportFormat() { +293 return reportFormat; +294 } +295 +296 /** +297 * Set the value of reportFormat. +298 * +299 * @param reportFormat new value of reportFormat +300 */ +301 public void setReportFormat(ReportFormats reportFormat) { +302 this.reportFormat = reportFormat.getValue(); +303 } +304 /** +305 * The Proxy Server. 306 */ -307 public void setReportFormat(ReportFormats reportFormat) { -308 this.reportFormat = reportFormat.getValue(); -309 } -310 /** -311 * The Proxy Server. -312 */ -313 private String proxyServer; -314 -315 /** -316 * Get the value of proxyServer. -317 * -318 * @return the value of proxyServer -319 */ -320 public String getProxyServer() { -321 return proxyServer; -322 } -323 -324 /** -325 * Set the value of proxyServer. -326 * -327 * @param server new value of proxyServer -328 */ -329 public void setProxyServer(String server) { -330 this.proxyServer = server; -331 } -332 -333 /** -334 * Get the value of proxyServer. -335 * -336 * @return the value of proxyServer -337 * @deprecated use {@link org.owasp.dependencycheck.taskdefs.DependencyCheckTask#getProxyServer()} instead -338 */ -339 @Deprecated -340 public String getProxyUrl() { -341 return proxyServer; -342 } -343 -344 /** -345 * Set the value of proxyServer. -346 * -347 * @param proxyUrl new value of proxyServer -348 * @deprecated use {@link org.owasp.dependencycheck.taskdefs.DependencyCheckTask#setProxyServer(java.lang.String)} instead -349 */ -350 @Deprecated -351 public void setProxyUrl(String proxyUrl) { -352 LOGGER.warning("A deprecated configuration option 'proxyUrl' was detected; use 'proxyServer' instead."); -353 this.proxyServer = proxyUrl; -354 } -355 /** -356 * The Proxy Port. -357 */ -358 private String proxyPort; -359 -360 /** -361 * Get the value of proxyPort. -362 * -363 * @return the value of proxyPort -364 */ -365 public String getProxyPort() { -366 return proxyPort; -367 } -368 -369 /** -370 * Set the value of proxyPort. -371 * -372 * @param proxyPort new value of proxyPort +307 private String proxyServer; +308 +309 /** +310 * Get the value of proxyServer. +311 * +312 * @return the value of proxyServer +313 */ +314 public String getProxyServer() { +315 return proxyServer; +316 } +317 +318 /** +319 * Set the value of proxyServer. +320 * +321 * @param server new value of proxyServer +322 */ +323 public void setProxyServer(String server) { +324 this.proxyServer = server; +325 } +326 +327 /** +328 * Get the value of proxyServer. +329 * +330 * @return the value of proxyServer +331 * @deprecated use {@link org.owasp.dependencycheck.taskdefs.DependencyCheckTask#getProxyServer()} instead +332 */ +333 @Deprecated +334 public String getProxyUrl() { +335 return proxyServer; +336 } +337 +338 /** +339 * Set the value of proxyServer. +340 * +341 * @param proxyUrl new value of proxyServer +342 * @deprecated use {@link org.owasp.dependencycheck.taskdefs.DependencyCheckTask#setProxyServer(java.lang.String)} instead +343 */ +344 @Deprecated +345 public void setProxyUrl(String proxyUrl) { +346 log("A deprecated configuration option 'proxyUrl' was detected; use 'proxyServer' instead.", Project.MSG_WARN); +347 this.proxyServer = proxyUrl; +348 } +349 /** +350 * The Proxy Port. +351 */ +352 private String proxyPort; +353 +354 /** +355 * Get the value of proxyPort. +356 * +357 * @return the value of proxyPort +358 */ +359 public String getProxyPort() { +360 return proxyPort; +361 } +362 +363 /** +364 * Set the value of proxyPort. +365 * +366 * @param proxyPort new value of proxyPort +367 */ +368 public void setProxyPort(String proxyPort) { +369 this.proxyPort = proxyPort; +370 } +371 /** +372 * The Proxy username. 373 */ -374 public void setProxyPort(String proxyPort) { -375 this.proxyPort = proxyPort; -376 } -377 /** -378 * The Proxy username. -379 */ -380 private String proxyUsername; -381 -382 /** -383 * Get the value of proxyUsername. -384 * -385 * @return the value of proxyUsername -386 */ -387 public String getProxyUsername() { -388 return proxyUsername; -389 } -390 -391 /** -392 * Set the value of proxyUsername. -393 * -394 * @param proxyUsername new value of proxyUsername +374 private String proxyUsername; +375 +376 /** +377 * Get the value of proxyUsername. +378 * +379 * @return the value of proxyUsername +380 */ +381 public String getProxyUsername() { +382 return proxyUsername; +383 } +384 +385 /** +386 * Set the value of proxyUsername. +387 * +388 * @param proxyUsername new value of proxyUsername +389 */ +390 public void setProxyUsername(String proxyUsername) { +391 this.proxyUsername = proxyUsername; +392 } +393 /** +394 * The Proxy password. 395 */ -396 public void setProxyUsername(String proxyUsername) { -397 this.proxyUsername = proxyUsername; -398 } -399 /** -400 * The Proxy password. -401 */ -402 private String proxyPassword; -403 -404 /** -405 * Get the value of proxyPassword. -406 * -407 * @return the value of proxyPassword -408 */ -409 public String getProxyPassword() { -410 return proxyPassword; -411 } -412 -413 /** -414 * Set the value of proxyPassword. -415 * -416 * @param proxyPassword new value of proxyPassword +396 private String proxyPassword; +397 +398 /** +399 * Get the value of proxyPassword. +400 * +401 * @return the value of proxyPassword +402 */ +403 public String getProxyPassword() { +404 return proxyPassword; +405 } +406 +407 /** +408 * Set the value of proxyPassword. +409 * +410 * @param proxyPassword new value of proxyPassword +411 */ +412 public void setProxyPassword(String proxyPassword) { +413 this.proxyPassword = proxyPassword; +414 } +415 /** +416 * The Connection Timeout. 417 */ -418 public void setProxyPassword(String proxyPassword) { -419 this.proxyPassword = proxyPassword; -420 } -421 /** -422 * The Connection Timeout. -423 */ -424 private String connectionTimeout; -425 -426 /** -427 * Get the value of connectionTimeout. -428 * -429 * @return the value of connectionTimeout -430 */ -431 public String getConnectionTimeout() { -432 return connectionTimeout; -433 } -434 -435 /** -436 * Set the value of connectionTimeout. -437 * -438 * @param connectionTimeout new value of connectionTimeout +418 private String connectionTimeout; +419 +420 /** +421 * Get the value of connectionTimeout. +422 * +423 * @return the value of connectionTimeout +424 */ +425 public String getConnectionTimeout() { +426 return connectionTimeout; +427 } +428 +429 /** +430 * Set the value of connectionTimeout. +431 * +432 * @param connectionTimeout new value of connectionTimeout +433 */ +434 public void setConnectionTimeout(String connectionTimeout) { +435 this.connectionTimeout = connectionTimeout; +436 } +437 /** +438 * The path to the suppression file. 439 */ -440 public void setConnectionTimeout(String connectionTimeout) { -441 this.connectionTimeout = connectionTimeout; -442 } -443 /** -444 * The file path used for verbose logging. -445 */ -446 private String logFile = null; -447 -448 /** -449 * Get the value of logFile. -450 * -451 * @return the value of logFile -452 */ -453 public String getLogFile() { -454 return logFile; -455 } -456 -457 /** -458 * Set the value of logFile. -459 * -460 * @param logFile new value of logFile +440 private String suppressionFile; +441 +442 /** +443 * Get the value of suppressionFile. +444 * +445 * @return the value of suppressionFile +446 */ +447 public String getSuppressionFile() { +448 return suppressionFile; +449 } +450 +451 /** +452 * Set the value of suppressionFile. +453 * +454 * @param suppressionFile new value of suppressionFile +455 */ +456 public void setSuppressionFile(String suppressionFile) { +457 this.suppressionFile = suppressionFile; +458 } +459 /** +460 * flag indicating whether or not to show a summary of findings. 461 */ -462 public void setLogFile(String logFile) { -463 this.logFile = logFile; -464 } -465 /** -466 * The path to the suppression file. -467 */ -468 private String suppressionFile; -469 -470 /** -471 * Get the value of suppressionFile. -472 * -473 * @return the value of suppressionFile -474 */ -475 public String getSuppressionFile() { -476 return suppressionFile; -477 } -478 -479 /** -480 * Set the value of suppressionFile. -481 * -482 * @param suppressionFile new value of suppressionFile -483 */ -484 public void setSuppressionFile(String suppressionFile) { -485 this.suppressionFile = suppressionFile; -486 } -487 /** -488 * flag indicating whether or not to show a summary of findings. -489 */ -490 private boolean showSummary = true; -491 -492 /** -493 * Get the value of showSummary. -494 * -495 * @return the value of showSummary -496 */ -497 public boolean isShowSummary() { -498 return showSummary; -499 } -500 -501 /** -502 * Set the value of showSummary. -503 * -504 * @param showSummary new value of showSummary +462 private boolean showSummary = true; +463 +464 /** +465 * Get the value of showSummary. +466 * +467 * @return the value of showSummary +468 */ +469 public boolean isShowSummary() { +470 return showSummary; +471 } +472 +473 /** +474 * Set the value of showSummary. +475 * +476 * @param showSummary new value of showSummary +477 */ +478 public void setShowSummary(boolean showSummary) { +479 this.showSummary = showSummary; +480 } +481 +482 /** +483 * Sets whether or not the analyzer is enabled. +484 * +485 * @param jarAnalyzerEnabled the value of the new setting +486 */ +487 public void setJarAnalyzerEnabled(boolean jarAnalyzerEnabled) { +488 this.jarAnalyzerEnabled = jarAnalyzerEnabled; +489 } +490 /** +491 * Whether or not the Archive Analyzer is enabled. +492 */ +493 private boolean archiveAnalyzerEnabled = true; +494 +495 /** +496 * Returns whether or not the analyzer is enabled. +497 * +498 * @return true if the analyzer is enabled +499 */ +500 public boolean isArchiveAnalyzerEnabled() { +501 return archiveAnalyzerEnabled; +502 } +503 /** +504 * Whether or not the .NET Assembly Analyzer is enabled. 505 */ -506 public void setShowSummary(boolean showSummary) { -507 this.showSummary = showSummary; -508 } -509 -510 /** -511 * Sets whether or not the analyzer is enabled. -512 * -513 * @param jarAnalyzerEnabled the value of the new setting -514 */ -515 public void setJarAnalyzerEnabled(boolean jarAnalyzerEnabled) { -516 this.jarAnalyzerEnabled = jarAnalyzerEnabled; -517 } -518 /** -519 * Whether or not the Archive Analyzer is enabled. -520 */ -521 private boolean archiveAnalyzerEnabled = true; -522 -523 /** -524 * Returns whether or not the analyzer is enabled. -525 * -526 * @return true if the analyzer is enabled -527 */ -528 public boolean isArchiveAnalyzerEnabled() { -529 return archiveAnalyzerEnabled; -530 } -531 /** -532 * Whether or not the .NET Assembly Analyzer is enabled. -533 */ -534 private boolean assemblyAnalyzerEnabled = true; -535 -536 /** -537 * Sets whether or not the analyzer is enabled. -538 * -539 * @param archiveAnalyzerEnabled the value of the new setting -540 */ -541 public void setArchiveAnalyzerEnabled(boolean archiveAnalyzerEnabled) { -542 this.archiveAnalyzerEnabled = archiveAnalyzerEnabled; -543 } -544 -545 /** -546 * Returns whether or not the analyzer is enabled. -547 * -548 * @return true if the analyzer is enabled -549 */ -550 public boolean isAssemblyAnalyzerEnabled() { -551 return assemblyAnalyzerEnabled; -552 } -553 -554 /** -555 * Sets whether or not the analyzer is enabled. -556 * -557 * @param assemblyAnalyzerEnabled the value of the new setting +506 private boolean assemblyAnalyzerEnabled = true; +507 +508 /** +509 * Sets whether or not the analyzer is enabled. +510 * +511 * @param archiveAnalyzerEnabled the value of the new setting +512 */ +513 public void setArchiveAnalyzerEnabled(boolean archiveAnalyzerEnabled) { +514 this.archiveAnalyzerEnabled = archiveAnalyzerEnabled; +515 } +516 +517 /** +518 * Returns whether or not the analyzer is enabled. +519 * +520 * @return true if the analyzer is enabled +521 */ +522 public boolean isAssemblyAnalyzerEnabled() { +523 return assemblyAnalyzerEnabled; +524 } +525 +526 /** +527 * Sets whether or not the analyzer is enabled. +528 * +529 * @param assemblyAnalyzerEnabled the value of the new setting +530 */ +531 public void setAssemblyAnalyzerEnabled(boolean assemblyAnalyzerEnabled) { +532 this.assemblyAnalyzerEnabled = assemblyAnalyzerEnabled; +533 } +534 /** +535 * Whether or not the .NET Nuspec Analyzer is enabled. +536 */ +537 private boolean nuspecAnalyzerEnabled = true; +538 +539 /** +540 * Returns whether or not the analyzer is enabled. +541 * +542 * @return true if the analyzer is enabled +543 */ +544 public boolean isNuspecAnalyzerEnabled() { +545 return nuspecAnalyzerEnabled; +546 } +547 +548 /** +549 * Sets whether or not the analyzer is enabled. +550 * +551 * @param nuspecAnalyzerEnabled the value of the new setting +552 */ +553 public void setNuspecAnalyzerEnabled(boolean nuspecAnalyzerEnabled) { +554 this.nuspecAnalyzerEnabled = nuspecAnalyzerEnabled; +555 } +556 /** +557 * Whether or not the central analyzer is enabled. 558 */ -559 public void setAssemblyAnalyzerEnabled(boolean assemblyAnalyzerEnabled) { -560 this.assemblyAnalyzerEnabled = assemblyAnalyzerEnabled; -561 } -562 /** -563 * Whether or not the .NET Nuspec Analyzer is enabled. -564 */ -565 private boolean nuspecAnalyzerEnabled = true; -566 -567 /** -568 * Returns whether or not the analyzer is enabled. -569 * -570 * @return true if the analyzer is enabled -571 */ -572 public boolean isNuspecAnalyzerEnabled() { -573 return nuspecAnalyzerEnabled; -574 } -575 -576 /** -577 * Sets whether or not the analyzer is enabled. -578 * -579 * @param nuspecAnalyzerEnabled the value of the new setting -580 */ -581 public void setNuspecAnalyzerEnabled(boolean nuspecAnalyzerEnabled) { -582 this.nuspecAnalyzerEnabled = nuspecAnalyzerEnabled; -583 } +559 private boolean centralAnalyzerEnabled = false; +560 +561 /** +562 * Get the value of centralAnalyzerEnabled. +563 * +564 * @return the value of centralAnalyzerEnabled +565 */ +566 public boolean isCentralAnalyzerEnabled() { +567 return centralAnalyzerEnabled; +568 } +569 +570 /** +571 * Set the value of centralAnalyzerEnabled. +572 * +573 * @param centralAnalyzerEnabled new value of centralAnalyzerEnabled +574 */ +575 public void setCentralAnalyzerEnabled(boolean centralAnalyzerEnabled) { +576 this.centralAnalyzerEnabled = centralAnalyzerEnabled; +577 } +578 +579 /** +580 * Whether or not the nexus analyzer is enabled. +581 */ +582 private boolean nexusAnalyzerEnabled = true; +583 584 /** -585 * Whether or not the central analyzer is enabled. -586 */ -587 private boolean centralAnalyzerEnabled = false; -588 -589 /** -590 * Get the value of centralAnalyzerEnabled. -591 * -592 * @return the value of centralAnalyzerEnabled -593 */ -594 public boolean isCentralAnalyzerEnabled() { -595 return centralAnalyzerEnabled; -596 } -597 -598 /** -599 * Set the value of centralAnalyzerEnabled. -600 * -601 * @param centralAnalyzerEnabled new value of centralAnalyzerEnabled -602 */ -603 public void setCentralAnalyzerEnabled(boolean centralAnalyzerEnabled) { -604 this.centralAnalyzerEnabled = centralAnalyzerEnabled; -605 } +585 * Get the value of nexusAnalyzerEnabled. +586 * +587 * @return the value of nexusAnalyzerEnabled +588 */ +589 public boolean isNexusAnalyzerEnabled() { +590 return nexusAnalyzerEnabled; +591 } +592 +593 /** +594 * Set the value of nexusAnalyzerEnabled. +595 * +596 * @param nexusAnalyzerEnabled new value of nexusAnalyzerEnabled +597 */ +598 public void setNexusAnalyzerEnabled(boolean nexusAnalyzerEnabled) { +599 this.nexusAnalyzerEnabled = nexusAnalyzerEnabled; +600 } +601 +602 /** +603 * The URL of a Nexus server's REST API end point (http://domain/nexus/service/local). +604 */ +605 private String nexusUrl; 606 607 /** -608 * Whether or not the nexus analyzer is enabled. -609 */ -610 private boolean nexusAnalyzerEnabled = true; -611 -612 /** -613 * Get the value of nexusAnalyzerEnabled. -614 * -615 * @return the value of nexusAnalyzerEnabled -616 */ -617 public boolean isNexusAnalyzerEnabled() { -618 return nexusAnalyzerEnabled; -619 } -620 -621 /** -622 * Set the value of nexusAnalyzerEnabled. -623 * -624 * @param nexusAnalyzerEnabled new value of nexusAnalyzerEnabled -625 */ -626 public void setNexusAnalyzerEnabled(boolean nexusAnalyzerEnabled) { -627 this.nexusAnalyzerEnabled = nexusAnalyzerEnabled; -628 } -629 -630 /** -631 * The URL of a Nexus server's REST API end point (http://domain/nexus/service/local). -632 */ -633 private String nexusUrl; -634 -635 /** -636 * Get the value of nexusUrl. -637 * -638 * @return the value of nexusUrl -639 */ -640 public String getNexusUrl() { -641 return nexusUrl; -642 } -643 -644 /** -645 * Set the value of nexusUrl. -646 * -647 * @param nexusUrl new value of nexusUrl -648 */ -649 public void setNexusUrl(String nexusUrl) { -650 this.nexusUrl = nexusUrl; -651 } +608 * Get the value of nexusUrl. +609 * +610 * @return the value of nexusUrl +611 */ +612 public String getNexusUrl() { +613 return nexusUrl; +614 } +615 +616 /** +617 * Set the value of nexusUrl. +618 * +619 * @param nexusUrl new value of nexusUrl +620 */ +621 public void setNexusUrl(String nexusUrl) { +622 this.nexusUrl = nexusUrl; +623 } +624 /** +625 * Whether or not the defined proxy should be used when connecting to Nexus. +626 */ +627 private boolean nexusUsesProxy = true; +628 +629 /** +630 * Get the value of nexusUsesProxy. +631 * +632 * @return the value of nexusUsesProxy +633 */ +634 public boolean isNexusUsesProxy() { +635 return nexusUsesProxy; +636 } +637 +638 /** +639 * Set the value of nexusUsesProxy. +640 * +641 * @param nexusUsesProxy new value of nexusUsesProxy +642 */ +643 public void setNexusUsesProxy(boolean nexusUsesProxy) { +644 this.nexusUsesProxy = nexusUsesProxy; +645 } +646 +647 /** +648 * The database driver name; such as org.h2.Driver. +649 */ +650 private String databaseDriverName; +651 652 /** -653 * Whether or not the defined proxy should be used when connecting to Nexus. -654 */ -655 private boolean nexusUsesProxy = true; -656 -657 /** -658 * Get the value of nexusUsesProxy. -659 * -660 * @return the value of nexusUsesProxy -661 */ -662 public boolean isNexusUsesProxy() { -663 return nexusUsesProxy; -664 } -665 -666 /** -667 * Set the value of nexusUsesProxy. -668 * -669 * @param nexusUsesProxy new value of nexusUsesProxy -670 */ -671 public void setNexusUsesProxy(boolean nexusUsesProxy) { -672 this.nexusUsesProxy = nexusUsesProxy; -673 } +653 * Get the value of databaseDriverName. +654 * +655 * @return the value of databaseDriverName +656 */ +657 public String getDatabaseDriverName() { +658 return databaseDriverName; +659 } +660 +661 /** +662 * Set the value of databaseDriverName. +663 * +664 * @param databaseDriverName new value of databaseDriverName +665 */ +666 public void setDatabaseDriverName(String databaseDriverName) { +667 this.databaseDriverName = databaseDriverName; +668 } +669 +670 /** +671 * The path to the database driver JAR file if it is not on the class path. +672 */ +673 private String databaseDriverPath; 674 675 /** -676 * The database driver name; such as org.h2.Driver. -677 */ -678 private String databaseDriverName; -679 -680 /** -681 * Get the value of databaseDriverName. -682 * -683 * @return the value of databaseDriverName -684 */ -685 public String getDatabaseDriverName() { -686 return databaseDriverName; -687 } -688 -689 /** -690 * Set the value of databaseDriverName. -691 * -692 * @param databaseDriverName new value of databaseDriverName -693 */ -694 public void setDatabaseDriverName(String databaseDriverName) { -695 this.databaseDriverName = databaseDriverName; -696 } -697 -698 /** -699 * The path to the database driver JAR file if it is not on the class path. -700 */ -701 private String databaseDriverPath; -702 -703 /** -704 * Get the value of databaseDriverPath. -705 * -706 * @return the value of databaseDriverPath -707 */ -708 public String getDatabaseDriverPath() { -709 return databaseDriverPath; -710 } -711 -712 /** -713 * Set the value of databaseDriverPath. -714 * -715 * @param databaseDriverPath new value of databaseDriverPath +676 * Get the value of databaseDriverPath. +677 * +678 * @return the value of databaseDriverPath +679 */ +680 public String getDatabaseDriverPath() { +681 return databaseDriverPath; +682 } +683 +684 /** +685 * Set the value of databaseDriverPath. +686 * +687 * @param databaseDriverPath new value of databaseDriverPath +688 */ +689 public void setDatabaseDriverPath(String databaseDriverPath) { +690 this.databaseDriverPath = databaseDriverPath; +691 } +692 /** +693 * The database connection string. +694 */ +695 private String connectionString; +696 +697 /** +698 * Get the value of connectionString. +699 * +700 * @return the value of connectionString +701 */ +702 public String getConnectionString() { +703 return connectionString; +704 } +705 +706 /** +707 * Set the value of connectionString. +708 * +709 * @param connectionString new value of connectionString +710 */ +711 public void setConnectionString(String connectionString) { +712 this.connectionString = connectionString; +713 } +714 /** +715 * The user name for connecting to the database. 716 */ -717 public void setDatabaseDriverPath(String databaseDriverPath) { -718 this.databaseDriverPath = databaseDriverPath; -719 } -720 /** -721 * The database connection string. -722 */ -723 private String connectionString; -724 -725 /** -726 * Get the value of connectionString. -727 * -728 * @return the value of connectionString -729 */ -730 public String getConnectionString() { -731 return connectionString; -732 } -733 -734 /** -735 * Set the value of connectionString. -736 * -737 * @param connectionString new value of connectionString -738 */ -739 public void setConnectionString(String connectionString) { -740 this.connectionString = connectionString; -741 } +717 private String databaseUser; +718 +719 /** +720 * Get the value of databaseUser. +721 * +722 * @return the value of databaseUser +723 */ +724 public String getDatabaseUser() { +725 return databaseUser; +726 } +727 +728 /** +729 * Set the value of databaseUser. +730 * +731 * @param databaseUser new value of databaseUser +732 */ +733 public void setDatabaseUser(String databaseUser) { +734 this.databaseUser = databaseUser; +735 } +736 +737 /** +738 * The password to use when connecting to the database. +739 */ +740 private String databasePassword; +741 742 /** -743 * The user name for connecting to the database. -744 */ -745 private String databaseUser; -746 -747 /** -748 * Get the value of databaseUser. -749 * -750 * @return the value of databaseUser -751 */ -752 public String getDatabaseUser() { -753 return databaseUser; -754 } -755 -756 /** -757 * Set the value of databaseUser. -758 * -759 * @param databaseUser new value of databaseUser -760 */ -761 public void setDatabaseUser(String databaseUser) { -762 this.databaseUser = databaseUser; -763 } -764 -765 /** -766 * The password to use when connecting to the database. -767 */ -768 private String databasePassword; -769 -770 /** -771 * Get the value of databasePassword. -772 * -773 * @return the value of databasePassword -774 */ -775 public String getDatabasePassword() { -776 return databasePassword; -777 } -778 -779 /** -780 * Set the value of databasePassword. -781 * -782 * @param databasePassword new value of databasePassword -783 */ -784 public void setDatabasePassword(String databasePassword) { -785 this.databasePassword = databasePassword; -786 } -787 -788 /** -789 * Additional ZIP File extensions to add analyze. This should be a comma-separated list of file extensions to treat like ZIP -790 * files. -791 */ -792 private String zipExtensions; -793 -794 /** -795 * Get the value of zipExtensions. -796 * -797 * @return the value of zipExtensions -798 */ -799 public String getZipExtensions() { -800 return zipExtensions; -801 } -802 -803 /** -804 * Set the value of zipExtensions. -805 * -806 * @param zipExtensions new value of zipExtensions -807 */ -808 public void setZipExtensions(String zipExtensions) { -809 this.zipExtensions = zipExtensions; -810 } +743 * Get the value of databasePassword. +744 * +745 * @return the value of databasePassword +746 */ +747 public String getDatabasePassword() { +748 return databasePassword; +749 } +750 +751 /** +752 * Set the value of databasePassword. +753 * +754 * @param databasePassword new value of databasePassword +755 */ +756 public void setDatabasePassword(String databasePassword) { +757 this.databasePassword = databasePassword; +758 } +759 +760 /** +761 * Additional ZIP File extensions to add analyze. This should be a comma-separated list of file extensions to treat like ZIP +762 * files. +763 */ +764 private String zipExtensions; +765 +766 /** +767 * Get the value of zipExtensions. +768 * +769 * @return the value of zipExtensions +770 */ +771 public String getZipExtensions() { +772 return zipExtensions; +773 } +774 +775 /** +776 * Set the value of zipExtensions. +777 * +778 * @param zipExtensions new value of zipExtensions +779 */ +780 public void setZipExtensions(String zipExtensions) { +781 this.zipExtensions = zipExtensions; +782 } +783 +784 /** +785 * The url for the modified NVD CVE (1.2 schema). +786 */ +787 private String cveUrl12Modified; +788 +789 /** +790 * Get the value of cveUrl12Modified. +791 * +792 * @return the value of cveUrl12Modified +793 */ +794 public String getCveUrl12Modified() { +795 return cveUrl12Modified; +796 } +797 +798 /** +799 * Set the value of cveUrl12Modified. +800 * +801 * @param cveUrl12Modified new value of cveUrl12Modified +802 */ +803 public void setCveUrl12Modified(String cveUrl12Modified) { +804 this.cveUrl12Modified = cveUrl12Modified; +805 } +806 +807 /** +808 * The url for the modified NVD CVE (2.0 schema). +809 */ +810 private String cveUrl20Modified; 811 812 /** -813 * The url for the modified NVD CVE (1.2 schema). -814 */ -815 private String cveUrl12Modified; -816 -817 /** -818 * Get the value of cveUrl12Modified. -819 * -820 * @return the value of cveUrl12Modified -821 */ -822 public String getCveUrl12Modified() { -823 return cveUrl12Modified; -824 } -825 -826 /** -827 * Set the value of cveUrl12Modified. -828 * -829 * @param cveUrl12Modified new value of cveUrl12Modified -830 */ -831 public void setCveUrl12Modified(String cveUrl12Modified) { -832 this.cveUrl12Modified = cveUrl12Modified; -833 } +813 * Get the value of cveUrl20Modified. +814 * +815 * @return the value of cveUrl20Modified +816 */ +817 public String getCveUrl20Modified() { +818 return cveUrl20Modified; +819 } +820 +821 /** +822 * Set the value of cveUrl20Modified. +823 * +824 * @param cveUrl20Modified new value of cveUrl20Modified +825 */ +826 public void setCveUrl20Modified(String cveUrl20Modified) { +827 this.cveUrl20Modified = cveUrl20Modified; +828 } +829 +830 /** +831 * Base Data Mirror URL for CVE 1.2. +832 */ +833 private String cveUrl12Base; 834 835 /** -836 * The url for the modified NVD CVE (2.0 schema). -837 */ -838 private String cveUrl20Modified; -839 -840 /** -841 * Get the value of cveUrl20Modified. -842 * -843 * @return the value of cveUrl20Modified -844 */ -845 public String getCveUrl20Modified() { -846 return cveUrl20Modified; -847 } -848 -849 /** -850 * Set the value of cveUrl20Modified. -851 * -852 * @param cveUrl20Modified new value of cveUrl20Modified -853 */ -854 public void setCveUrl20Modified(String cveUrl20Modified) { -855 this.cveUrl20Modified = cveUrl20Modified; -856 } +836 * Get the value of cveUrl12Base. +837 * +838 * @return the value of cveUrl12Base +839 */ +840 public String getCveUrl12Base() { +841 return cveUrl12Base; +842 } +843 +844 /** +845 * Set the value of cveUrl12Base. +846 * +847 * @param cveUrl12Base new value of cveUrl12Base +848 */ +849 public void setCveUrl12Base(String cveUrl12Base) { +850 this.cveUrl12Base = cveUrl12Base; +851 } +852 +853 /** +854 * Data Mirror URL for CVE 2.0. +855 */ +856 private String cveUrl20Base; 857 858 /** -859 * Base Data Mirror URL for CVE 1.2. -860 */ -861 private String cveUrl12Base; -862 -863 /** -864 * Get the value of cveUrl12Base. -865 * -866 * @return the value of cveUrl12Base -867 */ -868 public String getCveUrl12Base() { -869 return cveUrl12Base; -870 } -871 -872 /** -873 * Set the value of cveUrl12Base. -874 * -875 * @param cveUrl12Base new value of cveUrl12Base -876 */ -877 public void setCveUrl12Base(String cveUrl12Base) { -878 this.cveUrl12Base = cveUrl12Base; -879 } -880 -881 /** -882 * Data Mirror URL for CVE 2.0. -883 */ -884 private String cveUrl20Base; -885 -886 /** -887 * Get the value of cveUrl20Base. -888 * -889 * @return the value of cveUrl20Base -890 */ -891 public String getCveUrl20Base() { -892 return cveUrl20Base; -893 } -894 -895 /** -896 * Set the value of cveUrl20Base. -897 * -898 * @param cveUrl20Base new value of cveUrl20Base -899 */ -900 public void setCveUrl20Base(String cveUrl20Base) { -901 this.cveUrl20Base = cveUrl20Base; -902 } -903 /** -904 * The path to Mono for .NET assembly analysis on non-windows systems. -905 */ -906 private String pathToMono; -907 -908 /** -909 * Get the value of pathToMono. -910 * -911 * @return the value of pathToMono -912 */ -913 public String getPathToMono() { -914 return pathToMono; -915 } -916 -917 /** -918 * Set the value of pathToMono. -919 * -920 * @param pathToMono new value of pathToMono -921 */ -922 public void setPathToMono(String pathToMono) { -923 this.pathToMono = pathToMono; -924 } -925 -926 @Override -927 public void execute() throws BuildException { -928 final InputStream in = DependencyCheckTask.class.getClassLoader().getResourceAsStream(LOG_PROPERTIES_FILE); -929 LogUtils.prepareLogger(in, logFile); -930 -931 dealWithReferences(); -932 validateConfiguration(); -933 populateSettings(); -934 -935 Engine engine = null; -936 try { -937 engine = new Engine(DependencyCheckTask.class.getClassLoader()); -938 //todo - should this be its own task? -939 if (updateOnly) { -940 engine.doUpdates(); -941 } else { -942 try { -943 for (Resource resource : path) { -944 final FileProvider provider = resource.as(FileProvider.class); -945 if (provider != null) { -946 final File file = provider.getFile(); -947 if (file != null && file.exists()) { -948 engine.scan(file); -949 } -950 } -951 } -952 -953 engine.analyzeDependencies(); -954 DatabaseProperties prop = null; -955 CveDB cve = null; -956 try { -957 cve = new CveDB(); -958 cve.open(); -959 prop = cve.getDatabaseProperties(); -960 } catch (DatabaseException ex) { -961 LOGGER.log(Level.FINE, "Unable to retrieve DB Properties", ex); -962 } finally { -963 if (cve != null) { -964 cve.close(); -965 } -966 } -967 final ReportGenerator reporter = new ReportGenerator(applicationName, engine.getDependencies(), engine.getAnalyzers(), prop); -968 reporter.generateReports(reportOutputDirectory, reportFormat); -969 -970 if (this.failBuildOnCVSS <= 10) { -971 checkForFailure(engine.getDependencies()); -972 } -973 if (this.showSummary) { -974 showSummary(engine.getDependencies()); -975 } -976 } catch (IOException ex) { -977 LOGGER.log(Level.FINE, "Unable to generate dependency-check report", ex); -978 throw new BuildException("Unable to generate dependency-check report", ex); -979 } catch (Exception ex) { -980 LOGGER.log(Level.FINE, "An exception occurred; unable to continue task", ex); -981 throw new BuildException("An exception occurred; unable to continue task", ex); -982 } -983 } -984 } catch (DatabaseException ex) { -985 LOGGER.log(Level.SEVERE, "Unable to connect to the dependency-check database; analysis has stopped"); -986 LOGGER.log(Level.FINE, "", ex); -987 } finally { -988 Settings.cleanup(true); -989 if (engine != null) { -990 engine.cleanup(); -991 } -992 } -993 } -994 -995 /** -996 * Validate the configuration to ensure the parameters have been properly configured/initialized. -997 * -998 * @throws BuildException if the task was not configured correctly. -999 */ -1000 private void validateConfiguration() throws BuildException { -1001 if (path == null) { -1002 throw new BuildException("No project dependencies have been defined to analyze."); -1003 } -1004 if (failBuildOnCVSS < 0 || failBuildOnCVSS > 11) { -1005 throw new BuildException("Invalid configuration, failBuildOnCVSS must be between 0 and 11."); +859 * Get the value of cveUrl20Base. +860 * +861 * @return the value of cveUrl20Base +862 */ +863 public String getCveUrl20Base() { +864 return cveUrl20Base; +865 } +866 +867 /** +868 * Set the value of cveUrl20Base. +869 * +870 * @param cveUrl20Base new value of cveUrl20Base +871 */ +872 public void setCveUrl20Base(String cveUrl20Base) { +873 this.cveUrl20Base = cveUrl20Base; +874 } +875 /** +876 * The path to Mono for .NET assembly analysis on non-windows systems. +877 */ +878 private String pathToMono; +879 +880 /** +881 * Get the value of pathToMono. +882 * +883 * @return the value of pathToMono +884 */ +885 public String getPathToMono() { +886 return pathToMono; +887 } +888 +889 /** +890 * Set the value of pathToMono. +891 * +892 * @param pathToMono new value of pathToMono +893 */ +894 public void setPathToMono(String pathToMono) { +895 this.pathToMono = pathToMono; +896 } +897 +898 @Override +899 public void execute() throws BuildException { +900 dealWithReferences(); +901 validateConfiguration(); +902 populateSettings(); +903 +904 Engine engine = null; +905 try { +906 engine = new Engine(DependencyCheckTask.class.getClassLoader()); +907 //todo - should this be its own task? +908 if (updateOnly) { +909 engine.doUpdates(); +910 } else { +911 try { +912 for (Resource resource : path) { +913 final FileProvider provider = resource.as(FileProvider.class); +914 if (provider != null) { +915 final File file = provider.getFile(); +916 if (file != null && file.exists()) { +917 engine.scan(file); +918 } +919 } +920 } +921 +922 engine.analyzeDependencies(); +923 DatabaseProperties prop = null; +924 CveDB cve = null; +925 try { +926 cve = new CveDB(); +927 cve.open(); +928 prop = cve.getDatabaseProperties(); +929 } catch (DatabaseException ex) { +930 log("Unable to retrieve DB Properties", ex, Project.MSG_DEBUG); +931 } finally { +932 if (cve != null) { +933 cve.close(); +934 } +935 } +936 final ReportGenerator reporter = new ReportGenerator(applicationName, engine.getDependencies(), engine.getAnalyzers(), prop); +937 reporter.generateReports(reportOutputDirectory, reportFormat); +938 +939 if (this.failBuildOnCVSS <= 10) { +940 checkForFailure(engine.getDependencies()); +941 } +942 if (this.showSummary) { +943 showSummary(engine.getDependencies()); +944 } +945 } catch (IOException ex) { +946 log("Unable to generate dependency-check report", ex, Project.MSG_DEBUG); +947 throw new BuildException("Unable to generate dependency-check report", ex); +948 } catch (Exception ex) { +949 log("An exception occurred; unable to continue task", ex, Project.MSG_DEBUG); +950 throw new BuildException("An exception occurred; unable to continue task", ex); +951 } +952 } +953 } catch (DatabaseException ex) { +954 log("Unable to connect to the dependency-check database; analysis has stopped", ex, Project.MSG_ERR); +955 } finally { +956 Settings.cleanup(true); +957 if (engine != null) { +958 engine.cleanup(); +959 } +960 } +961 } +962 +963 /** +964 * Validate the configuration to ensure the parameters have been properly configured/initialized. +965 * +966 * @throws BuildException if the task was not configured correctly. +967 */ +968 private void validateConfiguration() throws BuildException { +969 if (path == null) { +970 throw new BuildException("No project dependencies have been defined to analyze."); +971 } +972 if (failBuildOnCVSS < 0 || failBuildOnCVSS > 11) { +973 throw new BuildException("Invalid configuration, failBuildOnCVSS must be between 0 and 11."); +974 } +975 } +976 +977 /** +978 * Takes the properties supplied and updates the dependency-check settings. Additionally, this sets the system properties +979 * required to change the proxy server, port, and connection timeout. +980 */ +981 private void populateSettings() { +982 Settings.initialize(); +983 InputStream taskProperties = null; +984 try { +985 taskProperties = this.getClass().getClassLoader().getResourceAsStream(PROPERTIES_FILE); +986 Settings.mergeProperties(taskProperties); +987 } catch (IOException ex) { +988 log("Unable to load the dependency-check ant task.properties file.", ex, Project.MSG_WARN); +989 } finally { +990 if (taskProperties != null) { +991 try { +992 taskProperties.close(); +993 } catch (IOException ex) { +994 log("", ex, Project.MSG_DEBUG); +995 } +996 } +997 } +998 if (dataDirectory != null) { +999 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory); +1000 } else { +1001 final File jarPath = new File(DependencyCheckTask.class.getProtectionDomain().getCodeSource().getLocation().getPath()); +1002 final File base = jarPath.getParentFile(); +1003 final String sub = Settings.getString(Settings.KEYS.DATA_DIRECTORY); +1004 final File dataDir = new File(base, sub); +1005 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath()); 1006 } -1007 } -1008 -1009 /** -1010 * Takes the properties supplied and updates the dependency-check settings. Additionally, this sets the system properties -1011 * required to change the proxy server, port, and connection timeout. -1012 */ -1013 private void populateSettings() { -1014 Settings.initialize(); -1015 InputStream taskProperties = null; -1016 try { -1017 taskProperties = this.getClass().getClassLoader().getResourceAsStream(PROPERTIES_FILE); -1018 Settings.mergeProperties(taskProperties); -1019 } catch (IOException ex) { -1020 LOGGER.log(Level.WARNING, "Unable to load the dependency-check ant task.properties file."); -1021 LOGGER.log(Level.FINE, null, ex); -1022 } finally { -1023 if (taskProperties != null) { -1024 try { -1025 taskProperties.close(); -1026 } catch (IOException ex) { -1027 LOGGER.log(Level.FINEST, null, ex); -1028 } -1029 } -1030 } -1031 if (dataDirectory != null) { -1032 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory); -1033 } else { -1034 final File jarPath = new File(DependencyCheckTask.class.getProtectionDomain().getCodeSource().getLocation().getPath()); -1035 final File base = jarPath.getParentFile(); -1036 final String sub = Settings.getString(Settings.KEYS.DATA_DIRECTORY); -1037 final File dataDir = new File(base, sub); -1038 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath()); -1039 } -1040 -1041 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate); -1042 -1043 if (proxyServer != null && !proxyServer.isEmpty()) { -1044 Settings.setString(Settings.KEYS.PROXY_SERVER, proxyServer); -1045 } -1046 if (proxyPort != null && !proxyPort.isEmpty()) { -1047 Settings.setString(Settings.KEYS.PROXY_PORT, proxyPort); -1048 } -1049 if (proxyUsername != null && !proxyUsername.isEmpty()) { -1050 Settings.setString(Settings.KEYS.PROXY_USERNAME, proxyUsername); +1007 +1008 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate); +1009 +1010 if (proxyServer != null && !proxyServer.isEmpty()) { +1011 Settings.setString(Settings.KEYS.PROXY_SERVER, proxyServer); +1012 } +1013 if (proxyPort != null && !proxyPort.isEmpty()) { +1014 Settings.setString(Settings.KEYS.PROXY_PORT, proxyPort); +1015 } +1016 if (proxyUsername != null && !proxyUsername.isEmpty()) { +1017 Settings.setString(Settings.KEYS.PROXY_USERNAME, proxyUsername); +1018 } +1019 if (proxyPassword != null && !proxyPassword.isEmpty()) { +1020 Settings.setString(Settings.KEYS.PROXY_PASSWORD, proxyPassword); +1021 } +1022 if (connectionTimeout != null && !connectionTimeout.isEmpty()) { +1023 Settings.setString(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout); +1024 } +1025 if (suppressionFile != null && !suppressionFile.isEmpty()) { +1026 Settings.setString(Settings.KEYS.SUPPRESSION_FILE, suppressionFile); +1027 } +1028 +1029 //File Type Analyzer Settings +1030 //JAR ANALYZER +1031 Settings.setBoolean(Settings.KEYS.ANALYZER_JAR_ENABLED, jarAnalyzerEnabled); +1032 //NUSPEC ANALYZER +1033 Settings.setBoolean(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, nuspecAnalyzerEnabled); +1034 //CENTRAL ANALYZER +1035 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, centralAnalyzerEnabled); +1036 //NEXUS ANALYZER +1037 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled); +1038 if (nexusUrl != null && !nexusUrl.isEmpty()) { +1039 Settings.setString(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl); +1040 } +1041 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_PROXY, nexusUsesProxy); +1042 //ARCHIVE ANALYZER +1043 Settings.setBoolean(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, archiveAnalyzerEnabled); +1044 if (zipExtensions != null && !zipExtensions.isEmpty()) { +1045 Settings.setString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions); +1046 } +1047 //ASSEMBLY ANALYZER +1048 Settings.setBoolean(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, assemblyAnalyzerEnabled); +1049 if (pathToMono != null && !pathToMono.isEmpty()) { +1050 Settings.setString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono); 1051 } -1052 if (proxyPassword != null && !proxyPassword.isEmpty()) { -1053 Settings.setString(Settings.KEYS.PROXY_PASSWORD, proxyPassword); -1054 } -1055 if (connectionTimeout != null && !connectionTimeout.isEmpty()) { -1056 Settings.setString(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout); -1057 } -1058 if (suppressionFile != null && !suppressionFile.isEmpty()) { -1059 Settings.setString(Settings.KEYS.SUPPRESSION_FILE, suppressionFile); -1060 } -1061 -1062 //File Type Analyzer Settings -1063 //JAR ANALYZER -1064 Settings.setBoolean(Settings.KEYS.ANALYZER_JAR_ENABLED, jarAnalyzerEnabled); -1065 //NUSPEC ANALYZER -1066 Settings.setBoolean(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, nuspecAnalyzerEnabled); -1067 //CENTRAL ANALYZER -1068 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, centralAnalyzerEnabled); -1069 //NEXUS ANALYZER -1070 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled); -1071 if (nexusUrl != null && !nexusUrl.isEmpty()) { -1072 Settings.setString(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl); +1052 +1053 if (databaseDriverName != null && !databaseDriverName.isEmpty()) { +1054 Settings.setString(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName); +1055 } +1056 if (databaseDriverPath != null && !databaseDriverPath.isEmpty()) { +1057 Settings.setString(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath); +1058 } +1059 if (connectionString != null && !connectionString.isEmpty()) { +1060 Settings.setString(Settings.KEYS.DB_CONNECTION_STRING, connectionString); +1061 } +1062 if (databaseUser != null && !databaseUser.isEmpty()) { +1063 Settings.setString(Settings.KEYS.DB_USER, databaseUser); +1064 } +1065 if (databasePassword != null && !databasePassword.isEmpty()) { +1066 Settings.setString(Settings.KEYS.DB_PASSWORD, databasePassword); +1067 } +1068 if (cveUrl12Modified != null && !cveUrl12Modified.isEmpty()) { +1069 Settings.setString(Settings.KEYS.CVE_MODIFIED_12_URL, cveUrl12Modified); +1070 } +1071 if (cveUrl20Modified != null && !cveUrl20Modified.isEmpty()) { +1072 Settings.setString(Settings.KEYS.CVE_MODIFIED_20_URL, cveUrl20Modified); 1073 } -1074 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_PROXY, nexusUsesProxy); -1075 //ARCHIVE ANALYZER -1076 Settings.setBoolean(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, archiveAnalyzerEnabled); -1077 if (zipExtensions != null && !zipExtensions.isEmpty()) { -1078 Settings.setString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions); +1074 if (cveUrl12Base != null && !cveUrl12Base.isEmpty()) { +1075 Settings.setString(Settings.KEYS.CVE_SCHEMA_1_2, cveUrl12Base); +1076 } +1077 if (cveUrl20Base != null && !cveUrl20Base.isEmpty()) { +1078 Settings.setString(Settings.KEYS.CVE_SCHEMA_2_0, cveUrl20Base); 1079 } -1080 //ASSEMBLY ANALYZER -1081 Settings.setBoolean(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, assemblyAnalyzerEnabled); -1082 if (pathToMono != null && !pathToMono.isEmpty()) { -1083 Settings.setString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono); -1084 } -1085 -1086 if (databaseDriverName != null && !databaseDriverName.isEmpty()) { -1087 Settings.setString(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName); -1088 } -1089 if (databaseDriverPath != null && !databaseDriverPath.isEmpty()) { -1090 Settings.setString(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath); -1091 } -1092 if (connectionString != null && !connectionString.isEmpty()) { -1093 Settings.setString(Settings.KEYS.DB_CONNECTION_STRING, connectionString); -1094 } -1095 if (databaseUser != null && !databaseUser.isEmpty()) { -1096 Settings.setString(Settings.KEYS.DB_USER, databaseUser); -1097 } -1098 if (databasePassword != null && !databasePassword.isEmpty()) { -1099 Settings.setString(Settings.KEYS.DB_PASSWORD, databasePassword); -1100 } -1101 if (cveUrl12Modified != null && !cveUrl12Modified.isEmpty()) { -1102 Settings.setString(Settings.KEYS.CVE_MODIFIED_12_URL, cveUrl12Modified); -1103 } -1104 if (cveUrl20Modified != null && !cveUrl20Modified.isEmpty()) { -1105 Settings.setString(Settings.KEYS.CVE_MODIFIED_20_URL, cveUrl20Modified); -1106 } -1107 if (cveUrl12Base != null && !cveUrl12Base.isEmpty()) { -1108 Settings.setString(Settings.KEYS.CVE_SCHEMA_1_2, cveUrl12Base); -1109 } -1110 if (cveUrl20Base != null && !cveUrl20Base.isEmpty()) { -1111 Settings.setString(Settings.KEYS.CVE_SCHEMA_2_0, cveUrl20Base); -1112 } -1113 } -1114 -1115 /** -1116 * Checks to see if a vulnerability has been identified with a CVSS score that is above the threshold set in the -1117 * configuration. -1118 * -1119 * @param dependencies the list of dependency objects -1120 * @throws BuildException thrown if a CVSS score is found that is higher then the threshold set -1121 */ -1122 private void checkForFailure(List<Dependency> dependencies) throws BuildException { -1123 final StringBuilder ids = new StringBuilder(); -1124 for (Dependency d : dependencies) { -1125 for (Vulnerability v : d.getVulnerabilities()) { -1126 if (v.getCvssScore() >= failBuildOnCVSS) { -1127 if (ids.length() == 0) { -1128 ids.append(v.getName()); -1129 } else { -1130 ids.append(", ").append(v.getName()); -1131 } -1132 } -1133 } -1134 } -1135 if (ids.length() > 0) { -1136 final String msg = String.format("%n%nDependency-Check Failure:%n" -1137 + "One or more dependencies were identified with vulnerabilities that have a CVSS score greater then '%.1f': %s%n" -1138 + "See the dependency-check report for more details.%n%n", failBuildOnCVSS, ids.toString()); -1139 throw new BuildException(msg); -1140 } -1141 } -1142 -1143 /** -1144 * Generates a warning message listing a summary of dependencies and their associated CPE and CVE entries. -1145 * -1146 * @param dependencies a list of dependency objects -1147 */ -1148 private void showSummary(List<Dependency> dependencies) { -1149 final StringBuilder summary = new StringBuilder(); -1150 for (Dependency d : dependencies) { -1151 boolean firstEntry = true; -1152 final StringBuilder ids = new StringBuilder(); -1153 for (Vulnerability v : d.getVulnerabilities()) { -1154 if (firstEntry) { -1155 firstEntry = false; -1156 } else { -1157 ids.append(", "); -1158 } -1159 ids.append(v.getName()); -1160 } -1161 if (ids.length() > 0) { -1162 summary.append(d.getFileName()).append(" ("); -1163 firstEntry = true; -1164 for (Identifier id : d.getIdentifiers()) { -1165 if (firstEntry) { -1166 firstEntry = false; -1167 } else { -1168 summary.append(", "); -1169 } -1170 summary.append(id.getValue()); -1171 } -1172 summary.append(") : ").append(ids).append(NEW_LINE); -1173 } -1174 } -1175 if (summary.length() > 0) { -1176 final String msg = String.format("%n%n" -1177 + "One or more dependencies were identified with known vulnerabilities:%n%n%s" -1178 + "%n%nSee the dependency-check report for more details.%n%n", summary.toString()); -1179 LOGGER.log(Level.WARNING, msg); -1180 } -1181 } -1182 -1183 /** -1184 * An enumeration of supported report formats: "ALL", "HTML", "XML", "VULN", etc.. -1185 */ -1186 public static class ReportFormats extends EnumeratedAttribute { -1187 -1188 /** -1189 * Returns the list of values for the report format. -1190 * -1191 * @return the list of values for the report format -1192 */ -1193 @Override -1194 public String[] getValues() { -1195 int i = 0; -1196 final Format[] formats = Format.values(); -1197 final String[] values = new String[formats.length]; -1198 for (Format format : formats) { -1199 values[i++] = format.name(); -1200 } -1201 return values; -1202 } -1203 } -1204 -1205 /** -1206 * Whether or not the Jar Analyzer is enabled. -1207 */ -1208 private boolean jarAnalyzerEnabled = true; -1209 -1210 /** -1211 * Returns whether or not the analyzer is enabled. -1212 * -1213 * @return true if the analyzer is enabled -1214 */ -1215 public boolean isJarAnalyzerEnabled() { -1216 return jarAnalyzerEnabled; -1217 } -1218 } +1080 } +1081 +1082 /** +1083 * Checks to see if a vulnerability has been identified with a CVSS score that is above the threshold set in the +1084 * configuration. +1085 * +1086 * @param dependencies the list of dependency objects +1087 * @throws BuildException thrown if a CVSS score is found that is higher then the threshold set +1088 */ +1089 private void checkForFailure(List<Dependency> dependencies) throws BuildException { +1090 final StringBuilder ids = new StringBuilder(); +1091 for (Dependency d : dependencies) { +1092 for (Vulnerability v : d.getVulnerabilities()) { +1093 if (v.getCvssScore() >= failBuildOnCVSS) { +1094 if (ids.length() == 0) { +1095 ids.append(v.getName()); +1096 } else { +1097 ids.append(", ").append(v.getName()); +1098 } +1099 } +1100 } +1101 } +1102 if (ids.length() > 0) { +1103 final String msg = String.format("%n%nDependency-Check Failure:%n" +1104 + "One or more dependencies were identified with vulnerabilities that have a CVSS score greater then '%.1f': %s%n" +1105 + "See the dependency-check report for more details.%n%n", failBuildOnCVSS, ids.toString()); +1106 throw new BuildException(msg); +1107 } +1108 } +1109 +1110 /** +1111 * Generates a warning message listing a summary of dependencies and their associated CPE and CVE entries. +1112 * +1113 * @param dependencies a list of dependency objects +1114 */ +1115 private void showSummary(List<Dependency> dependencies) { +1116 final StringBuilder summary = new StringBuilder(); +1117 for (Dependency d : dependencies) { +1118 boolean firstEntry = true; +1119 final StringBuilder ids = new StringBuilder(); +1120 for (Vulnerability v : d.getVulnerabilities()) { +1121 if (firstEntry) { +1122 firstEntry = false; +1123 } else { +1124 ids.append(", "); +1125 } +1126 ids.append(v.getName()); +1127 } +1128 if (ids.length() > 0) { +1129 summary.append(d.getFileName()).append(" ("); +1130 firstEntry = true; +1131 for (Identifier id : d.getIdentifiers()) { +1132 if (firstEntry) { +1133 firstEntry = false; +1134 } else { +1135 summary.append(", "); +1136 } +1137 summary.append(id.getValue()); +1138 } +1139 summary.append(") : ").append(ids).append(NEW_LINE); +1140 } +1141 } +1142 if (summary.length() > 0) { +1143 final String msg = String.format("%n%n" +1144 + "One or more dependencies were identified with known vulnerabilities:%n%n%s" +1145 + "%n%nSee the dependency-check report for more details.%n%n", summary.toString()); +1146 log(msg, Project.MSG_WARN); +1147 } +1148 } +1149 +1150 /** +1151 * An enumeration of supported report formats: "ALL", "HTML", "XML", "VULN", etc.. +1152 */ +1153 public static class ReportFormats extends EnumeratedAttribute { +1154 +1155 /** +1156 * Returns the list of values for the report format. +1157 * +1158 * @return the list of values for the report format +1159 */ +1160 @Override +1161 public String[] getValues() { +1162 int i = 0; +1163 final Format[] formats = Format.values(); +1164 final String[] values = new String[formats.length]; +1165 for (Format format : formats) { +1166 values[i++] = format.name(); +1167 } +1168 return values; +1169 } +1170 } +1171 +1172 /** +1173 * Whether or not the Jar Analyzer is enabled. +1174 */ +1175 private boolean jarAnalyzerEnabled = true; +1176 +1177 /** +1178 * Returns whether or not the analyzer is enabled. +1179 * +1180 * @return true if the analyzer is enabled +1181 */ +1182 public boolean isJarAnalyzerEnabled() { +1183 return jarAnalyzerEnabled; +1184 } +1185 }
    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 e4c24e8a6..8df1a5f24 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.2.11 Reference Package org.owasp.dependencycheck.taskdefs + Dependency-Check Ant Task 1.3.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 ee3356626..a67113cef 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.2.11 Reference Package org.owasp.dependencycheck.taskdefs + Dependency-Check Ant Task 1.3.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 new file mode 100644 index 000000000..b5993481e --- /dev/null +++ b/dependency-check-ant/xref/org/slf4j/impl/StaticLoggerBinder.html @@ -0,0 +1,116 @@ + + + +StaticLoggerBinder xref + + + +
    View Javadoc
    +1   /*
    +2    * This file is part of dependency-check-ant.
    +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) 2015 The OWASP Foundation. All Rights Reserved.
    +17   */
    +18  package org.slf4j.impl;
    +19  
    +20  import org.apache.tools.ant.Task;
    +21  import org.owasp.dependencycheck.ant.logging.AntLoggerFactory;
    +22  import org.slf4j.ILoggerFactory;
    +23  import org.slf4j.spi.LoggerFactoryBinder;
    +24  
    +25  /**
    +26   * The binding of {@link LoggerFactory} class with an actual instance of {@link ILoggerFactory} is performed using information
    +27   * returned by this class.
    +28   *
    +29   * @author colezlaw
    +30   */
    +31  public class StaticLoggerBinder implements LoggerFactoryBinder {
    +32  
    +33      /**
    +34       * The unique instance of this class
    +35       *
    +36       */
    +37      private static final StaticLoggerBinder SINGLETON = new StaticLoggerBinder();
    +38  
    +39      /**
    +40       * Return the singleton of this class.
    +41       *
    +42       * @return the StaticLoggerBinder singleton
    +43       */
    +44      public static final StaticLoggerBinder getSingleton() {
    +45          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      private 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       */
    +58      public void setTask(Task task) {
    +59          this.task = task;
    +60          loggerFactory = new AntLoggerFactory(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
    +68      public static String REQUESTED_API_VERSION = "1.7.12"; // final
    +69  
    +70      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       */
    +75      private ILoggerFactory loggerFactory;
    +76  
    +77      /**
    +78       * Constructs a new static logger binder.
    +79       */
    +80      private StaticLoggerBinder() {
    +81          loggerFactory = new AntLoggerFactory(task);
    +82      }
    +83  
    +84      /**
    +85       * Returns the logger factory.
    +86       *
    +87       * @return the logger factory
    +88       */
    +89      @Override
    +90      public ILoggerFactory getLoggerFactory() {
    +91          return loggerFactory;
    +92      }
    +93  
    +94      /**
    +95       * Returns the logger factory class string.
    +96       *
    +97       * @return the logger factory class string
    +98       */
    +99      @Override
    +100     public String getLoggerFactoryClassStr() {
    +101         return LOGGER_FACTORY_CLASS;
    +102     }
    +103 }
    +
    +
    + + + diff --git a/dependency-check-ant/xref/org/slf4j/impl/package-frame.html b/dependency-check-ant/xref/org/slf4j/impl/package-frame.html new file mode 100644 index 000000000..ba38ec30d --- /dev/null +++ b/dependency-check-ant/xref/org/slf4j/impl/package-frame.html @@ -0,0 +1,24 @@ + + + + + + Dependency-Check Ant Task 1.3.0 Reference Package org.slf4j.impl + + + + +

    + org.slf4j.impl +

    + +

    Classes

    + + + + + \ No newline at end of file diff --git a/dependency-check-ant/xref/org/slf4j/impl/package-summary.html b/dependency-check-ant/xref/org/slf4j/impl/package-summary.html new file mode 100644 index 000000000..574f613a3 --- /dev/null +++ b/dependency-check-ant/xref/org/slf4j/impl/package-summary.html @@ -0,0 +1,69 @@ + + + + + + Dependency-Check Ant Task 1.3.0 Reference Package org.slf4j.impl + + + +
    + +
    +
    + +
    + +

    Package org.slf4j.impl

    + + + + + + + + + + + + +
    Class Summary
    + StaticLoggerBinder +
    + +
    + +
    +
    + +
    +
    + + + \ No newline at end of file diff --git a/dependency-check-ant/xref/overview-frame.html b/dependency-check-ant/xref/overview-frame.html index 2bd616ad4..c31684d5b 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.2.11 Reference + Dependency-Check Ant Task 1.3.0 Reference @@ -16,7 +16,13 @@ diff --git a/dependency-check-ant/xref/overview-summary.html b/dependency-check-ant/xref/overview-summary.html index b3d2b39a3..c1fc2ce69 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.2.11 Reference + Dependency-Check Ant Task 1.3.0 Reference @@ -24,7 +24,7 @@ -

    Dependency-Check Ant Task 1.2.11 Reference

    +

    Dependency-Check Ant Task 1.3.0 Reference

    @@ -34,9 +34,19 @@ + + + + + +
    + org.owasp.dependencycheck.ant.logging +
    org.owasp.dependencycheck.taskdefs
    + org.slf4j.impl +
    diff --git a/dependency-check-cli/apidocs/allclasses-frame.html b/dependency-check-cli/apidocs/allclasses-frame.html index bee559e76..1655e2fab 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.2.11 API) - +All Classes (Dependency-Check Command Line 1.3.0 API) + diff --git a/dependency-check-cli/apidocs/allclasses-noframe.html b/dependency-check-cli/apidocs/allclasses-noframe.html index 26ce500d8..cb227e09f 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.2.11 API) - +All Classes (Dependency-Check Command Line 1.3.0 API) + diff --git a/dependency-check-cli/apidocs/constant-values.html b/dependency-check-cli/apidocs/constant-values.html index 4b7b03df3..2d4704a09 100644 --- a/dependency-check-cli/apidocs/constant-values.html +++ b/dependency-check-cli/apidocs/constant-values.html @@ -2,16 +2,16 @@ - + -Constant Field Values (Dependency-Check Command Line 1.2.11 API) - +Constant Field Values (Dependency-Check Command Line 1.3.0 API) + @@ -133,6 +133,34 @@ "c" + + +public static final String +CVE_BASE_12 +"cveUrl12Base" + + + + +public static final String +CVE_BASE_20 +"cveUrl20Base" + + + + +public static final String +CVE_MOD_12 +"cveUrl12Modified" + + + + +public static final String +CVE_MOD_20 +"cveUrl20Modified" + + public static final String @@ -203,12 +231,26 @@ "n" + + +public static final String +DISABLE_AUTOCONF +"disableAutoconf" + + public static final String DISABLE_CENTRAL "disableCentral" + + + +public static final String +DISABLE_CMAKE +"disableCmake" + @@ -231,159 +273,173 @@ "disableNuspec" + + +public static final String +DISABLE_OPENSSL +"disableOpenSSL" + + public static final String DISABLE_PY_DIST "disablePyDist" - + public static final String DISABLE_PY_PKG "disablePyPkg" - + public static final String EXCLUDE "exclude" - + public static final String HELP "help" - + public static final String HELP_SHORT "h" - + public static final String NEXUS_URL "nexus" - + public static final String NEXUS_USES_PROXY "nexusUsesProxy" - + public static final String OUT "out" - + public static final String OUT_SHORT "o" - + public static final String OUTPUT_FORMAT "format" - + public static final String OUTPUT_FORMAT_SHORT "f" - + public static final String PATH_TO_MONO "mono" - + public static final String PROP "propertyfile" - + public static final String PROP_SHORT "P" - + public static final String PROXY_PASSWORD "proxypass" - + public static final String PROXY_PORT "proxyport" - + public static final String PROXY_SERVER "proxyserver" - + public static final String PROXY_URL "proxyurl" - + public static final String PROXY_USERNAME "proxyuser" - + public static final String SCAN "scan" - + public static final String SCAN_SHORT "s" - + public static final String SUPPRESSION_FILE "suppression" + + + +public static final String +SYM_LINK_DEPTH +"symLink" + @@ -468,6 +524,6 @@ -

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

    +

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

    diff --git a/dependency-check-cli/apidocs/deprecated-list.html b/dependency-check-cli/apidocs/deprecated-list.html index 9ccfdb045..42183731f 100644 --- a/dependency-check-cli/apidocs/deprecated-list.html +++ b/dependency-check-cli/apidocs/deprecated-list.html @@ -2,16 +2,16 @@ - + -Deprecated List (Dependency-Check Command Line 1.2.11 API) - +Deprecated List (Dependency-Check Command Line 1.3.0 API) + @@ -82,7 +82,7 @@ org.owasp.dependencycheck.CliParser.ARGUMENT.PROXY_URL -
    use cli.CliParser.ArgumentName instead
    +
    use CliParser.ARGUMENT.PROXY_SERVER instead
    @@ -134,6 +134,6 @@ -

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

    +

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

    diff --git a/dependency-check-cli/apidocs/help-doc.html b/dependency-check-cli/apidocs/help-doc.html index 43e43fedc..a2a2d7efb 100644 --- a/dependency-check-cli/apidocs/help-doc.html +++ b/dependency-check-cli/apidocs/help-doc.html @@ -2,16 +2,16 @@ - + -API Help (Dependency-Check Command Line 1.2.11 API) - +API Help (Dependency-Check Command Line 1.3.0 API) + @@ -211,6 +211,6 @@ -

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

    +

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

    diff --git a/dependency-check-cli/apidocs/index-all.html b/dependency-check-cli/apidocs/index-all.html index 9f5b8784a..a2228ee7b 100644 --- a/dependency-check-cli/apidocs/index-all.html +++ b/dependency-check-cli/apidocs/index-all.html @@ -2,16 +2,16 @@ - + -Index (Dependency-Check Command Line 1.2.11 API) - +Index (Dependency-Check Command Line 1.3.0 API) + @@ -119,6 +119,22 @@
    The short CLI argument name indicating the connection timeout.
    +
    CVE_BASE_12 - Static variable in class org.owasp.dependencycheck.CliParser.ARGUMENT
    +
    +
    The CLI argument name for setting the URL for the CVE Data Files.
    +
    +
    CVE_BASE_20 - Static variable in class org.owasp.dependencycheck.CliParser.ARGUMENT
    +
    +
    The CLI argument name for setting the URL for the CVE Data Files.
    +
    +
    CVE_MOD_12 - Static variable in class org.owasp.dependencycheck.CliParser.ARGUMENT
    +
    +
    The CLI argument name for setting the URL for the CVE Data Files.
    +
    +
    CVE_MOD_20 - Static variable in class org.owasp.dependencycheck.CliParser.ARGUMENT
    +
    +
    The CLI argument name for setting the URL for the CVE Data Files.
    +
    @@ -165,10 +181,18 @@
    The short CLI argument name specifying that the CPE/CVE/etc.
    +
    DISABLE_AUTOCONF - Static variable in class org.owasp.dependencycheck.CliParser.ARGUMENT
    +
    +
    Disables the Autoconf Analyzer.
    +
    DISABLE_CENTRAL - Static variable in class org.owasp.dependencycheck.CliParser.ARGUMENT
    Disables the Central Analyzer.
    +
    DISABLE_CMAKE - Static variable in class org.owasp.dependencycheck.CliParser.ARGUMENT
    +
    +
    Disables the Cmake Analyzer.
    +
    DISABLE_JAR - Static variable in class org.owasp.dependencycheck.CliParser.ARGUMENT
    Disables the Jar Analyzer.
    @@ -181,6 +205,10 @@
    Disables the Nuspec Analyzer.
    +
    DISABLE_OPENSSL - Static variable in class org.owasp.dependencycheck.CliParser.ARGUMENT
    +
    +
    Disables the OpenSSL Analyzer.
    +
    DISABLE_PY_DIST - Static variable in class org.owasp.dependencycheck.CliParser.ARGUMENT
    Disables the Python Distribution Analyzer.
    @@ -195,6 +223,10 @@

    E

    +
    ensureCanonicalPath(String) - Method in class org.owasp.dependencycheck.App
    +
    +
    Takes a path and resolves it to be a canonical & absolute path.
    +
    EXCLUDE - Static variable in class org.owasp.dependencycheck.CliParser.ARGUMENT
    Exclude path argument.
    @@ -213,6 +245,14 @@
    Returns the application name specified on the command line.
    +
    getBaseCve12Url() - Method in class org.owasp.dependencycheck.CliParser
    +
    +
    Returns the base URL for the CVE 1.2 XMl file.
    +
    +
    getBaseCve20Url() - Method in class org.owasp.dependencycheck.CliParser
    +
    +
    Returns the base URL for the CVE 2.0 XMl file.
    +
    getConnectionString() - Method in class org.owasp.dependencycheck.CliParser
    Returns the database connection string if specified; otherwise null is returned.
    @@ -245,6 +285,14 @@
    Retrieves the list of excluded file patterns specified by the 'exclude' argument.
    +
    getModifiedCve12Url() - Method in class org.owasp.dependencycheck.CliParser
    +
    +
    Returns the URL for the modified CVE 1.2 XMl file.
    +
    +
    getModifiedCve20Url() - Method in class org.owasp.dependencycheck.CliParser
    +
    +
    Returns the URL for the modified CVE 2.0 XMl file.
    +
    getNexusUrl() - Method in class org.owasp.dependencycheck.CliParser
    Returns the url to the nexus server if one was specified.
    @@ -289,6 +337,10 @@
    Returns the path to the suppression file.
    +
    getSymLinkDepth() - Method in class org.owasp.dependencycheck.CliParser
    +
    +
    Returns the symbolic link depth (how deeply symbolic links will be followed).
    +
    getVerboseLog() - Method in class org.owasp.dependencycheck.CliParser
    Returns the path to the verbose log file.
    @@ -321,6 +373,10 @@
    Returns true if the disableAssembly command line argument was specified.
    +
    isAutoconfDisabled() - Method in class org.owasp.dependencycheck.CliParser
    +
    +
    Returns true if the disableAutoconf command line argument was specified.
    +
    isAutoUpdate() - Method in class org.owasp.dependencycheck.CliParser
    Checks if the auto update feature has been disabled.
    @@ -329,6 +385,10 @@
    Returns true if the disableCentral command line argument was specified.
    +
    isCmakeDisabled() - Method in class org.owasp.dependencycheck.CliParser
    +
    +
    Returns true if the disableCmake command line argument was specified.
    +
    isGetHelp() - Method in class org.owasp.dependencycheck.CliParser
    Determines if the 'help' command line argument was passed in.
    @@ -353,6 +413,10 @@
    Returns true if the disableNuspec command line argument was specified.
    +
    isOpenSSLDisabled() - Method in class org.owasp.dependencycheck.CliParser
    +
    +
    Returns true if the disableOpenSSL command line argument was specified.
    +
    isPythonDistributionDisabled() - Method in class org.owasp.dependencycheck.CliParser
    Returns true if the disablePyDist command line argument was specified.
    @@ -465,7 +529,7 @@
    PROXY_URL - Static variable in class org.owasp.dependencycheck.CliParser.ARGUMENT
    Deprecated. - +
    PROXY_USERNAME - Static variable in class org.owasp.dependencycheck.CliParser.ARGUMENT
    @@ -500,6 +564,10 @@
    The CLI argument name for setting the location of the suppression file.
    +
    SYM_LINK_DEPTH - Static variable in class org.owasp.dependencycheck.CliParser.ARGUMENT
    +
    +
    The CLI argument name for setting the depth of symbolic links that will be followed.
    +
    @@ -578,6 +646,6 @@ -

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

    +

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

    diff --git a/dependency-check-cli/apidocs/index.html b/dependency-check-cli/apidocs/index.html index 8495c1df8..5d3f36491 100644 --- a/dependency-check-cli/apidocs/index.html +++ b/dependency-check-cli/apidocs/index.html @@ -2,9 +2,9 @@ - + -Dependency-Check Command Line 1.2.11 API +Dependency-Check Command Line 1.3.0 API @@ -137,12 +137,18 @@ extends Method and Description +protected String +ensureCanonicalPath(String path) +
    Takes a path and resolves it to be a canonical & absolute path.
    + + + static void main(String[] args)
    The main method for the application.
    - + void run(String[] args)
    Main CLI entry-point into the application.
    @@ -201,7 +207,7 @@ extends - @@ -275,6 +295,6 @@ extends Copyright© 2012-15 Jeremy Long. All Rights Reserved.

    +

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

    diff --git a/dependency-check-cli/apidocs/org/owasp/dependencycheck/CliParser.ARGUMENT.html b/dependency-check-cli/apidocs/org/owasp/dependencycheck/CliParser.ARGUMENT.html index 40e99c458..1b72d89dd 100644 --- a/dependency-check-cli/apidocs/org/owasp/dependencycheck/CliParser.ARGUMENT.html +++ b/dependency-check-cli/apidocs/org/owasp/dependencycheck/CliParser.ARGUMENT.html @@ -2,16 +2,16 @@ - + -CliParser.ARGUMENT (Dependency-Check Command Line 1.2.11 API) - +CliParser.ARGUMENT (Dependency-Check Command Line 1.3.0 API) + @@ -165,6 +165,30 @@ extends
    static String +CVE_BASE_12 +
    The CLI argument name for setting the URL for the CVE Data Files.
    + + + +static String +CVE_BASE_20 +
    The CLI argument name for setting the URL for the CVE Data Files.
    + + + +static String +CVE_MOD_12 +
    The CLI argument name for setting the URL for the CVE Data Files.
    + + + +static String +CVE_MOD_20 +
    The CLI argument name for setting the URL for the CVE Data Files.
    + + + +static String DATA_DIRECTORY
    The CLI argument name for setting the location of the data directory.
    @@ -225,10 +249,22 @@ extends static String +DISABLE_AUTOCONF +
    Disables the Autoconf Analyzer.
    + + + +static String DISABLE_CENTRAL
    Disables the Central Analyzer.
    + +static String +DISABLE_CMAKE +
    Disables the Cmake Analyzer.
    + + static String DISABLE_JAR @@ -249,138 +285,150 @@ extends static String +DISABLE_OPENSSL +
    Disables the OpenSSL Analyzer.
    + + + +static String DISABLE_PY_DIST
    Disables the Python Distribution Analyzer.
    - + static String DISABLE_PY_PKG
    Disables the Python Package Analyzer.
    - + static String EXCLUDE
    Exclude path argument.
    - + static String HELP
    The long CLI argument name asking for help.
    - + static String HELP_SHORT
    The short CLI argument name asking for help.
    - + static String NEXUS_URL
    The URL of the nexus server.
    - + static String NEXUS_USES_PROXY
    Whether or not the defined proxy should be used when connecting to Nexus.
    - + static String OUT
    The long CLI argument name specifying the directory to write the reports to.
    - + static String OUT_SHORT
    The short CLI argument name specifying the directory to write the reports to.
    - + static String OUTPUT_FORMAT
    The long CLI argument name specifying the output format to write the reports to.
    - + static String OUTPUT_FORMAT_SHORT
    The short CLI argument name specifying the output format to write the reports to.
    - + static String PATH_TO_MONO
    The CLI argument name for setting the path to mono for .NET Assembly analysis on non-windows systems.
    - + static String PROP
    The CLI argument name for setting the location of an additional properties file.
    - + static String PROP_SHORT
    The short CLI argument name for setting the location of an additional properties file.
    - + static String PROXY_PASSWORD
    The CLI argument name indicating the proxy password.
    - + static String PROXY_PORT
    The CLI argument name indicating the proxy port.
    - + static String PROXY_SERVER
    The CLI argument name indicating the proxy server.
    - + static String PROXY_URL
    Deprecated.  - +
    use PROXY_SERVER instead
    - + static String PROXY_USERNAME
    The CLI argument name indicating the proxy username.
    - + static String SCAN
    The long CLI argument name specifying the directory/file to scan.
    - + static String SCAN_SHORT
    The short CLI argument name specifying the directory/file to scan.
    - + static String SUPPRESSION_FILE
    The CLI argument name for setting the location of the suppression file.
    + +static String +SYM_LINK_DEPTH +
    The CLI argument name for setting the depth of symbolic links that will be followed.
    + + static String UPDATE_ONLY @@ -664,7 +712,7 @@ extends @Deprecated public static final String PROXY_URL -
    Deprecated. use cli.CliParser.ArgumentName instead
    +
    Deprecated. use PROXY_SERVER instead
    The CLI argument name indicating the proxy url.
    See Also:
    Constant Field Values
    @@ -746,6 +794,50 @@ public static final See Also:
    Constant Field Values
    + + + + + + + + + + + + + + + + @@ -779,6 +871,17 @@ public static final See Also:
    Constant Field Values
    + + + + @@ -834,6 +937,28 @@ public static final See Also:
    Constant Field Values
    + + + + + + + + @@ -878,6 +1003,17 @@ public static final See Also:
    Constant Field Values
    + + + + @@ -1071,6 +1207,6 @@ public static final Copyright© 2012-15 Jeremy Long. All Rights Reserved.

    +

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

    diff --git a/dependency-check-cli/apidocs/org/owasp/dependencycheck/CliParser.html b/dependency-check-cli/apidocs/org/owasp/dependencycheck/CliParser.html index f459ba784..f8fcd5585 100644 --- a/dependency-check-cli/apidocs/org/owasp/dependencycheck/CliParser.html +++ b/dependency-check-cli/apidocs/org/owasp/dependencycheck/CliParser.html @@ -2,16 +2,16 @@ - + -CliParser (Dependency-Check Command Line 1.2.11 API) - +CliParser (Dependency-Check Command Line 1.3.0 API) + @@ -171,6 +171,18 @@ extends
    String +getBaseCve12Url() +
    Returns the base URL for the CVE 1.2 XMl file.
    + + + +String +getBaseCve20Url() +
    Returns the base URL for the CVE 2.0 XMl file.
    + + + +String getConnectionString()
    Returns the database connection string if specified; otherwise null is returned.
    @@ -219,6 +231,18 @@ extends String +getModifiedCve12Url() +
    Returns the URL for the modified CVE 1.2 XMl file.
    + + + +String +getModifiedCve20Url() +
    Returns the URL for the modified CVE 2.0 XMl file.
    + + + +String getNexusUrl()
    Returns the url to the nexus server if one was specified.
    @@ -284,23 +308,35 @@ extends +int +getSymLinkDepth() +
    Returns the symbolic link depth (how deeply symbolic links will be followed).
    + + + String getVerboseLog()
    Returns the path to the verbose log file.
    - + boolean isArchiveDisabled()
    Returns true if the disableArchive command line argument was specified.
    - + boolean isAssemblyDisabled()
    Returns true if the disableAssembly command line argument was specified.
    + +boolean +isAutoconfDisabled() +
    Returns true if the disableAutoconf command line argument was specified.
    + + boolean isAutoUpdate() @@ -315,40 +351,52 @@ extends boolean +isCmakeDisabled() +
    Returns true if the disableCmake command line argument was specified.
    + + + +boolean isGetHelp()
    Determines if the 'help' command line argument was passed in.
    - + boolean isGetVersion()
    Determines if the 'version' command line argument was passed in.
    - + boolean isJarDisabled()
    Returns true if the disableJar command line argument was specified.
    - + boolean isNexusDisabled()
    Returns true if the disableNexus command line argument was specified.
    - + boolean isNexusUsesProxy()
    Returns true if the Nexus Analyzer should use the configured proxy to connect to Nexus; otherwise false is returned.
    - + boolean isNuspecDisabled()
    Returns true if the disableNuspec command line argument was specified.
    + +boolean +isOpenSSLDisabled() +
    Returns true if the disableOpenSSL command line argument was specified.
    + + boolean isPythonDistributionDisabled() @@ -480,6 +528,17 @@ extends Returns:
    whether or not the 'scan' command line argument was passed in
    +
    + + + @@ -546,6 +605,28 @@ extends Returns:
    true if the disablePyPkg command line argument was specified; otherwise false
    +
    + + + + + + + @@ -557,6 +638,17 @@ extends Returns:
    true if the disableNexus command line argument was specified; otherwise false
    +
    + + + @@ -666,6 +758,50 @@ extends Returns:
    the application name.
    +
    + + + + + + + + + + + + + + + @@ -932,6 +1068,6 @@ extends Copyright© 2012-15 Jeremy Long. All Rights Reserved.

    +

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

    diff --git a/dependency-check-cli/apidocs/org/owasp/dependencycheck/class-use/App.html b/dependency-check-cli/apidocs/org/owasp/dependencycheck/class-use/App.html index e04c116a4..5be82f313 100644 --- a/dependency-check-cli/apidocs/org/owasp/dependencycheck/class-use/App.html +++ b/dependency-check-cli/apidocs/org/owasp/dependencycheck/class-use/App.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.App (Dependency-Check Command Line 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.App (Dependency-Check Command Line 1.3.0 API) + @@ -110,6 +110,6 @@
    -

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

    +

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

    diff --git a/dependency-check-cli/apidocs/org/owasp/dependencycheck/class-use/CliParser.ARGUMENT.html b/dependency-check-cli/apidocs/org/owasp/dependencycheck/class-use/CliParser.ARGUMENT.html index 03264382d..7bde7540a 100644 --- a/dependency-check-cli/apidocs/org/owasp/dependencycheck/class-use/CliParser.ARGUMENT.html +++ b/dependency-check-cli/apidocs/org/owasp/dependencycheck/class-use/CliParser.ARGUMENT.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.CliParser.ARGUMENT (Dependency-Check Command Line 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.CliParser.ARGUMENT (Dependency-Check Command Line 1.3.0 API) + @@ -110,6 +110,6 @@ -

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

    +

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

    diff --git a/dependency-check-cli/apidocs/org/owasp/dependencycheck/class-use/CliParser.html b/dependency-check-cli/apidocs/org/owasp/dependencycheck/class-use/CliParser.html index c7e0063d6..e91c2da63 100644 --- a/dependency-check-cli/apidocs/org/owasp/dependencycheck/class-use/CliParser.html +++ b/dependency-check-cli/apidocs/org/owasp/dependencycheck/class-use/CliParser.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.CliParser (Dependency-Check Command Line 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.CliParser (Dependency-Check Command Line 1.3.0 API) + @@ -110,6 +110,6 @@ -

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

    +

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

    diff --git a/dependency-check-cli/apidocs/org/owasp/dependencycheck/package-frame.html b/dependency-check-cli/apidocs/org/owasp/dependencycheck/package-frame.html index 3b9585a91..82a914c59 100644 --- a/dependency-check-cli/apidocs/org/owasp/dependencycheck/package-frame.html +++ b/dependency-check-cli/apidocs/org/owasp/dependencycheck/package-frame.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck (Dependency-Check Command Line 1.2.11 API) - +org.owasp.dependencycheck (Dependency-Check Command Line 1.3.0 API) + 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 354cbb956..30fd05847 100644 --- a/dependency-check-cli/apidocs/org/owasp/dependencycheck/package-summary.html +++ b/dependency-check-cli/apidocs/org/owasp/dependencycheck/package-summary.html @@ -2,16 +2,16 @@ - + -org.owasp.dependencycheck (Dependency-Check Command Line 1.2.11 API) - +org.owasp.dependencycheck (Dependency-Check Command Line 1.3.0 API) + @@ -151,6 +151,6 @@ -

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

    +

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

    diff --git a/dependency-check-cli/apidocs/org/owasp/dependencycheck/package-tree.html b/dependency-check-cli/apidocs/org/owasp/dependencycheck/package-tree.html index a8ec99207..24a05f467 100644 --- a/dependency-check-cli/apidocs/org/owasp/dependencycheck/package-tree.html +++ b/dependency-check-cli/apidocs/org/owasp/dependencycheck/package-tree.html @@ -2,16 +2,16 @@ - + -org.owasp.dependencycheck Class Hierarchy (Dependency-Check Command Line 1.2.11 API) - +org.owasp.dependencycheck Class Hierarchy (Dependency-Check Command Line 1.3.0 API) + @@ -121,6 +121,6 @@ -

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

    +

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

    diff --git a/dependency-check-cli/apidocs/org/owasp/dependencycheck/package-use.html b/dependency-check-cli/apidocs/org/owasp/dependencycheck/package-use.html index 5d108de9b..c4598ca01 100644 --- a/dependency-check-cli/apidocs/org/owasp/dependencycheck/package-use.html +++ b/dependency-check-cli/apidocs/org/owasp/dependencycheck/package-use.html @@ -2,16 +2,16 @@ - + -Uses of Package org.owasp.dependencycheck (Dependency-Check Command Line 1.2.11 API) - +Uses of Package org.owasp.dependencycheck (Dependency-Check Command Line 1.3.0 API) + @@ -110,6 +110,6 @@ -

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

    +

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

    diff --git a/dependency-check-cli/apidocs/overview-tree.html b/dependency-check-cli/apidocs/overview-tree.html index d994b4e68..02b73ff6b 100644 --- a/dependency-check-cli/apidocs/overview-tree.html +++ b/dependency-check-cli/apidocs/overview-tree.html @@ -2,16 +2,16 @@ - + -Class Hierarchy (Dependency-Check Command Line 1.2.11 API) - +Class Hierarchy (Dependency-Check Command Line 1.3.0 API) + @@ -125,6 +125,6 @@ -

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

    +

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

    diff --git a/dependency-check-cli/arguments.html b/dependency-check-cli/arguments.html index e8c6acb23..a8e0258c5 100644 --- a/dependency-check-cli/arguments.html +++ b/dependency-check-cli/arguments.html @@ -1,13 +1,13 @@ - + dependency-check-cli - Command Line Arguments @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -103,7 +103,7 @@ Project Information - +
  • @@ -207,13 +207,26 @@ <pattern> -The path patterns to exclude from the scan - this option can be specified multiple times. This accepts Ant style path patterns (e.g. /exclude/) . +The path patterns to exclude from the scan - this option can be specified multiple times. This accepts Ant style path patterns (e.g. /exclude/). Optional + + +--symLink + +<depth> + +The depth that symbolic links will be followed; the default is 0 meaning symbolic links will not be followed. + +Optional + + + + -o --out @@ -225,7 +238,7 @@ Optional - + -f @@ -238,7 +251,7 @@ Required - + -l @@ -251,7 +264,7 @@ Optional - + -n @@ -264,7 +277,7 @@ Optional - + @@ -277,7 +290,7 @@ Optional - + -h @@ -290,7 +303,7 @@ Optional - + @@ -303,7 +316,7 @@ Optional - + -v @@ -339,6 +352,58 @@ + + +--cveUrl12Modified + +<url> + +URL for the modified CVE 1.2 + +http://nvd.nist.gov/download/nvdcve-modified.xml + + + + + + +--cveUrl20Modified + +<url> + +URL for the modified CVE 2.0 + +http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-modified.xml + + + + + + +--cveUrl12Base + +<url> + +Base URL for each year’s CVE 1.2, the %d will be replaced with the year + +http://nvd.nist.gov/download/nvdcve-%d.xml + + + + + + +--cveUrl20Base + +<url> + +Base URL for each year’s CVE 2.0, the %d will be replaced with the year + +http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-%d.xml + + + + -P --propertyfile @@ -393,6 +458,45 @@ +--disableAutoconf + + + +Sets whether the Autoconf Analyzer will be used. + +false + + + + + + +--disableOpenSSL + + + +Sets whether the OpenSSL Analyzer will be used. + +false + + + + + + +--disableCmake + + + +Sets whether the Cmake Analyzer will be used. + +false + + + + + + --disableArchive @@ -402,7 +506,7 @@ false - + @@ -415,7 +519,7 @@   - + @@ -428,7 +532,7 @@ false - + @@ -441,7 +545,7 @@ false - + @@ -454,7 +558,7 @@ false - + @@ -467,7 +571,7 @@   - + @@ -480,7 +584,7 @@ true - + @@ -493,7 +597,7 @@ false - + @@ -506,7 +610,7 @@ false - + @@ -519,7 +623,7 @@   - + @@ -532,7 +636,7 @@   - + @@ -545,7 +649,7 @@   - + @@ -558,7 +662,7 @@   - + @@ -571,7 +675,7 @@   - + @@ -584,7 +688,7 @@   - + @@ -597,7 +701,7 @@   - + @@ -610,7 +714,7 @@   - + @@ -623,7 +727,7 @@   - + @@ -636,7 +740,7 @@   - + @@ -649,7 +753,7 @@   - + -d diff --git a/dependency-check-cli/checkstyle.html b/dependency-check-cli/checkstyle.html index c2262536b..5682a92a9 100644 --- a/dependency-check-cli/checkstyle.html +++ b/dependency-check-cli/checkstyle.html @@ -1,13 +1,13 @@ - + dependency-check-cli - Checkstyle Results @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -105,7 +105,7 @@ Project Information - +
  • @@ -176,9 +176,16 @@
  • - + - PMD + CPD Report +
  • + +
  • + + + + PMD Report
  • @@ -243,10 +250,10 @@ Warnings Warnings Errors Errors -14 +10 0 0 -1 +2

    Details

    @@ -258,8 +265,12 @@ Line Errors -Total number of methods is 47 (max allowed is 40). -42
    +Total number of methods is 55 (max allowed is 40). +43 + +Errors +'}' is not preceded with whitespace. +437 diff --git a/dependency-check-cli/checkstyle.rss b/dependency-check-cli/checkstyle.rss index a4ac45c02..be2fbac4f 100644 --- a/dependency-check-cli/checkstyle.rss +++ b/dependency-check-cli/checkstyle.rss @@ -25,8 +25,8 @@ under the License. en-us ©2012 - 2015 OWASP - File: 14, - Errors: 1, + <title>File: 10, + Errors: 2, Warnings: 0, Infos: 0 @@ -45,20 +45,6 @@ under the License. - - org/owasp/dependencycheck/App.java - - - 0 - - - 0 - - - 0 - - - src/main/java/org/owasp/dependencycheck/InvalidScanPathException.java @@ -74,7 +60,7 @@ under the License. - target/classes/log.properties + org/owasp/dependencycheck/App.java 0 @@ -99,76 +85,6 @@ under the License. 0 - - - - src/main/java/org/owasp/dependencycheck/CliParser.java - - - 0 - - - 0 - - - 1 - - - - - target/maven-archiver/pom.properties - - - 0 - - - 0 - - - 0 - - - - - src/main/java/org/owasp/dependencycheck/App.java - - - 0 - - - 0 - - - 0 - - - - - src/main/resources/log.properties - - - 0 - - - 0 - - - 0 - - - - - target/generated-classes/cobertura/cobertura.properties - - - 0 - - - 0 - - - 0 - @@ -186,7 +102,7 @@ under the License. - target/generated-classes/cobertura/log.properties + src/main/java/org/owasp/dependencycheck/CliParser.java 0 @@ -195,12 +111,12 @@ under the License. 0 - 0 + 2 - log.properties + target/maven-archiver/pom.properties 0 @@ -239,6 +155,34 @@ under the License. 0 + + + + src/main/java/org/owasp/dependencycheck/App.java + + + 0 + + + 0 + + + 0 + + + + + target/generated-classes/cobertura/cobertura.properties + + + 0 + + + 0 + + + 0 + diff --git a/dependency-check-cli/cobertura/frame-sourcefiles-org.owasp.dependencycheck.html b/dependency-check-cli/cobertura/frame-sourcefiles-org.owasp.dependencycheck.html index e0b841e6a..be4c0f69e 100644 --- a/dependency-check-cli/cobertura/frame-sourcefiles-org.owasp.dependencycheck.html +++ b/dependency-check-cli/cobertura/frame-sourcefiles-org.owasp.dependencycheck.html @@ -15,10 +15,10 @@ org.owasp.dependencycheck - + - + diff --git a/dependency-check-cli/cobertura/frame-sourcefiles.html b/dependency-check-cli/cobertura/frame-sourcefiles.html index e000634bc..fafc4405b 100644 --- a/dependency-check-cli/cobertura/frame-sourcefiles.html +++ b/dependency-check-cli/cobertura/frame-sourcefiles.html @@ -15,10 +15,10 @@ All Packages
    App (0%)App (10%)
    CliParser (61%)CliParser (58%)
    InvalidScanPathException (0%)
    - + - + diff --git a/dependency-check-cli/cobertura/frame-summary-org.owasp.dependencycheck.html b/dependency-check-cli/cobertura/frame-summary-org.owasp.dependencycheck.html index a1d520e83..099a9006e 100644 --- a/dependency-check-cli/cobertura/frame-summary-org.owasp.dependencycheck.html +++ b/dependency-check-cli/cobertura/frame-summary-org.owasp.dependencycheck.html @@ -16,7 +16,7 @@
    App (0%)App (10%)
    CliParser (61%)CliParser (58%)
    InvalidScanPathException (0%)
    - +
    Package # Classes Line Coverage Branch Coverage Complexity
    org.owasp.dependencycheck4
    27%
    103/373
    15%
    35/232
    3.143
    org.owasp.dependencycheck4
    31%
    144/464
    17%
    50/288
    3.239
    - + diff --git a/dependency-check-cli/cobertura/frame-summary.html b/dependency-check-cli/cobertura/frame-summary.html index 0319498ae..d867fb93f 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
    27%
    103/373
    15%
    35/232
    3.143
    org.owasp.dependencycheck4
    27%
    103/373
    15%
    35/232
    3.143
    All Packages4
    31%
    144/464
    17%
    50/288
    3.239
    org.owasp.dependencycheck4
    31%
    144/464
    17%
    50/288
    3.239
    - + diff --git a/dependency-check-cli/cobertura/org.owasp.dependencycheck.App.html b/dependency-check-cli/cobertura/org.owasp.dependencycheck.App.html index 0df4419df..d79d957c3 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
    0%
    0/197
    0%
    0/122
    14.2
    App
    10%
    27/255
    6%
    10/144
    10.625
     
    @@ -56,17 +56,17 @@  19  
     
     20   -
     import java.io.File;
    +
     import ch.qos.logback.classic.LoggerContext;
     21   -
     import java.io.FileNotFoundException;
    +
     import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
     22   -
     import java.io.IOException;
    +
     import java.io.File;
     23   -
     import java.io.InputStream;
    +
     import java.io.FileNotFoundException;
     24   -
     import java.util.ArrayList;
    +
     import java.io.IOException;
     25   -
     import java.util.Arrays;
    +
     import java.util.ArrayList;
     26  
     import java.util.HashSet;
     27   @@ -74,464 +74,598 @@  28  
     import java.util.Set;
     29   -
     import java.util.logging.Level;
    -  30   -
     import java.util.logging.Logger;
    -  31  
     import org.apache.commons.cli.ParseException;
    -  32   +  30  
     import org.owasp.dependencycheck.data.nvdcve.CveDB;
    -  33   +  31  
     import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
    -  34   +  32  
     import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties;
    -  35   +  33  
     import org.owasp.dependencycheck.dependency.Dependency;
    -  36   +  34  
     import org.owasp.dependencycheck.org.apache.tools.ant.DirectoryScanner;
    -  37   +  35  
     import org.owasp.dependencycheck.reporting.ReportGenerator;
    -  38   -
     import org.owasp.dependencycheck.utils.LogUtils;
    -  39   +  36  
     import org.owasp.dependencycheck.utils.Settings;
    +  37   +
     import org.slf4j.Logger;
    +  38   +
     import org.slf4j.LoggerFactory;
    +  39   +
     import ch.qos.logback.core.FileAppender;
     40   -
     
    +
     import org.slf4j.impl.StaticLoggerBinder;
     41   -
     /**
    +
     
     42   -
      * The command line interface for the DependencyCheck application.
    +
     /**
     43   -
      *
    +
      * The command line interface for the DependencyCheck application.
     44   -
      * @author Jeremy Long
    +
      *
     45   +
      * @author Jeremy Long
    +  46  
      */
    -  46  0
     public class App {
    -  47   -
     
    +  47  16
     public class App {
     48   -
         /**
    +
     
     49   -
          * The location of the log properties configuration file.
    +
         /**
     50   -
          */
    -  51   -
         private static final String LOG_PROPERTIES_FILE = "log.properties";
    -  52   -
     
    -  53   -
         /**
    -  54  
          * The logger.
    +  51   +
          */
    +  52  8
         private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
    +  53   +
     
    +  54   +
         /**
     55   -
          */
    -  56  0
         private static final Logger LOGGER = Logger.getLogger(App.class.getName());
    -  57   -
     
    -  58   -
         /**
    -  59  
          * The main method for the application.
    -  60   +  56  
          *
    -  61   +  57  
          * @param args the command line arguments
    -  62   +  58  
          */
    -  63   +  59  
         public static void main(String[] args) {
    +  60   +
             try {
    +  61  0
                 Settings.initialize();
    +  62  0
                 final App app = new App();
    +  63  0
                 app.run(args);
     64   -
             try {
    -  65  0
                 Settings.initialize();
    -  66  0
                 final App app = new App();
    -  67  0
                 app.run(args);
    -  68  
             } finally {
    -  69  0
                 Settings.cleanup(true);
    -  70  0
             }
    -  71  0
         }
    -  72   +  65  0
                 Settings.cleanup(true);
    +  66  0
             }
    +  67  0
         }
    +  68  
     
    -  73   +  69  
         /**
    -  74   +  70  
          * Main CLI entry-point into the application.
    -  75   +  71  
          *
    -  76   +  72  
          * @param args the command line arguments
    -  77   +  73  
          */
    -  78   +  74  
         public void run(String[] args) {
    -  79  0
             final CliParser cli = new CliParser();
    -  80   +  75  0
             final CliParser cli = new CliParser();
    +  76  
     
    -  81   +  77  
             try {
    -  82  0
                 cli.parse(args);
    -  83  0
             } catch (FileNotFoundException ex) {
    +  78  0
                 cli.parse(args);
    +  79  0
             } catch (FileNotFoundException ex) {
    +  80  0
                 System.err.println(ex.getMessage());
    +  81  0
                 cli.printHelp();
    +  82  0
                 return;
    +  83  0
             } catch (ParseException ex) {
     84  0
                 System.err.println(ex.getMessage());
     85  0
                 cli.printHelp();
     86  0
                 return;
    -  87  0
             } catch (ParseException ex) {
    -  88  0
                 System.err.println(ex.getMessage());
    -  89  0
                 cli.printHelp();
    -  90  0
                 return;
    -  91  0
             }
    +  87  0
             }
    +  88   +
     
    +  89  0
             if (cli.getVerboseLog() != null) {
    +  90  0
                 prepareLogger(cli.getVerboseLog());
    +  91   +
             }
     92  
     
    -  93  0
             final InputStream in = App.class.getClassLoader().getResourceAsStream(LOG_PROPERTIES_FILE);
    -  94  0
             LogUtils.prepareLogger(in, cli.getVerboseLog());
    -  95   -
     
    -  96  0
             if (cli.isGetVersion()) {
    -  97  0
                 cli.printVersionInfo();
    -  98  0
             } else if (cli.isUpdateOnly()) {
    +  93  0
             if (cli.isGetVersion()) {
    +  94  0
                 cli.printVersionInfo();
    +  95  0
             } else if (cli.isUpdateOnly()) {
    +  96  0
                 populateSettings(cli);
    +  97  0
                 runUpdateOnly();
    +  98  0
             } else if (cli.isRunScan()) {
     99  0
                 populateSettings(cli);
    -  100  0
                 runUpdateOnly();
    -  101  0
             } else if (cli.isRunScan()) {
    -  102  0
                 populateSettings(cli);
    -  103   +  100  
                 try {
    -  104  0
                     runScan(cli.getReportDirectory(), cli.getReportFormat(), cli.getApplicationName(), cli.getScanFiles(), cli.getExcludeList());
    -  105  0
                 } catch (InvalidScanPathException ex) {
    -  106  0
                     LOGGER.log(Level.SEVERE, "An invalid scan path was detected; unable to scan '//*' paths");
    -  107  0
                 }
    -  108   +  101  0
                     runScan(cli.getReportDirectory(), cli.getReportFormat(), cli.getApplicationName(), cli.getScanFiles(),
    +  102   +
                             cli.getExcludeList(), cli.getSymLinkDepth());
    +  103  0
                 } catch (InvalidScanPathException ex) {
    +  104  0
                     LOGGER.error("An invalid scan path was detected; unable to scan '//*' paths");
    +  105  0
                 }
    +  106  
             } else {
    -  109  0
                 cli.printHelp();
    +  107  0
                 cli.printHelp();
    +  108   +
             }
    +  109  0
         }
     110   -
             }
    -  111  0
         }
    +
     
    +  111   +
         /**
     112   -
     
    -  113   -
         /**
    -  114  
          * Scans the specified directories and writes the dependency reports to the reportDirectory.
    -  115   +  113  
          *
    -  116   +  114  
          * @param reportDirectory the path to the directory where the reports will be written
    -  117   +  115  
          * @param outputFormat the output format of the report
    -  118   +  116  
          * @param applicationName the application name for the report
    -  119   +  117  
          * @param files the files/directories to scan
    -  120   +  118  
          * @param excludes the patterns for files/directories to exclude
    +  119   +
          * @param symLinkDepth the depth that symbolic links will be followed
    +  120   +
          *
     121   -
          *
    -  122  
          * @throws InvalidScanPathException thrown if the path to scan starts with "//"
    +  122   +
          */
     123   -
          */
    -  124  
         private void runScan(String reportDirectory, String outputFormat, String applicationName, String[] files,
    -  125   -
                 String[] excludes) throws InvalidScanPathException {
    -  126  0
             Engine engine = null;
    -  127   +  124   +
                 String[] excludes, int symLinkDepth) throws InvalidScanPathException {
    +  125  0
             Engine engine = null;
    +  126  
             try {
    -  128  0
                 engine = new Engine();
    -  129  0
                 List<String> antStylePaths = new ArrayList<String>();
    -  130  0
                 if (excludes == null || excludes.length == 0) {
    -  131  0
                     for (String file : files) {
    -  132  0
                         if (file.contains("*") || file.contains("?")) {
    -  133  0
                             antStylePaths.add(file);
    -  134   -
                         } else {
    -  135  0
                             engine.scan(file);
    -  136   -
                         }
    -  137   -
                     }
    -  138   -
                 } else {
    -  139  0
                     antStylePaths = Arrays.asList(files);
    -  140   +  127  0
                 engine = new Engine();
    +  128  0
                 final List<String> antStylePaths = new ArrayList<String>();
    +  129  0
                 for (String file : files) {
    +  130  0
                     final String antPath = ensureCanonicalPath(file);
    +  131  0
                     antStylePaths.add(antPath);
    +  132  
                 }
    -  141   +  133  
     
    -  142  0
                 final Set<File> paths = new HashSet<File>();
    -  143  0
                 for (String file : antStylePaths) {
    -  144  0
                     final DirectoryScanner scanner = new DirectoryScanner();
    -  145  0
                     String include = file.replace('\\', '/');
    -  146   +  134  0
                 final Set<File> paths = new HashSet<File>();
    +  135  0
                 for (String file : antStylePaths) {
    +  136  0
                     LOGGER.debug("Scanning {}", file);
    +  137  0
                     final DirectoryScanner scanner = new DirectoryScanner();
    +  138  0
                     String include = file.replace('\\', '/');
    +  139  
                     File baseDir;
    -  147   +  140  
     
    -  148  0
                     if (include.startsWith("//")) {
    -  149  0
                         throw new InvalidScanPathException("Unable to scan paths specified by //");
    -  150  0
                     } else if (include.startsWith("./")) {
    -  151  0
                         baseDir = new File(".");
    -  152  0
                         include = include.substring(2);
    -  153  0
                     } else if (include.startsWith("/")) {
    -  154  0
                         baseDir = new File("/");
    -  155  0
                         include = include.substring(1);
    -  156  0
                     } else if (include.contains("/")) {
    -  157  0
                         final int pos = include.indexOf('/');
    -  158  0
                         final String tmp = include.substring(0, pos);
    -  159  0
                         if (tmp.contains("*") || tmp.contains("?")) {
    -  160  0
                             baseDir = new File(".");
    -  161   +  141  0
                     if (include.startsWith("//")) {
    +  142  0
                         throw new InvalidScanPathException("Unable to scan paths specified by //");
    +  143   +
                     } else {
    +  144  0
                         final int pos = getLastFileSeparator(include);
    +  145  0
                         final String tmpBase = include.substring(0, pos);
    +  146  0
                         final String tmpInclude = include.substring(pos + 1);
    +  147  0
                         if (tmpInclude.indexOf('*') >= 0 || tmpInclude.indexOf('?') >= 0
    +  148   +
                                 || (new File(include)).isFile()) {
    +  149  0
                             baseDir = new File(tmpBase);
    +  150  0
                             include = tmpInclude;
    +  151  
                         } else {
    -  162  0
                             baseDir = new File(tmp);
    -  163  0
                             include = include.substring(pos + 1);
    -  164   +  152  0
                             baseDir = new File(tmpBase, tmpInclude);
    +  153  0
                             include = "**/*";
    +  154  
                         }
    -  165  0
                     } else { //no path info - must just be a file in the working directory
    -  166  0
                         baseDir = new File(".");
    -  167   +  155  
                     }
    -  168  0
                     scanner.setBasedir(baseDir);
    -  169  0
                     scanner.setIncludes(include);
    -  170  0
                     if (excludes != null && excludes.length > 0) {
    -  171  0
                         scanner.addExcludes(excludes);
    -  172   +  156   +
                     //LOGGER.debug("baseDir: {}", baseDir);
    +  157   +
                     //LOGGER.debug("include: {}", include);
    +  158  0
                     scanner.setBasedir(baseDir);
    +  159  0
                     scanner.setIncludes(include);
    +  160  0
                     scanner.setMaxLevelsOfSymlinks(symLinkDepth);
    +  161  0
                     if (symLinkDepth <= 0) {
    +  162  0
                         scanner.setFollowSymlinks(false);
    +  163  
                     }
    -  173  0
                     scanner.scan();
    -  174  0
                     if (scanner.getIncludedFilesCount() > 0) {
    -  175  0
                         for (String s : scanner.getIncludedFiles()) {
    -  176  0
                             final File f = new File(baseDir, s);
    -  177  0
                             paths.add(f);
    -  178   +  164  0
                     if (excludes != null && excludes.length > 0) {
    +  165  0
                         scanner.addExcludes(excludes);
    +  166   +
                     }
    +  167  0
                     scanner.scan();
    +  168  0
                     if (scanner.getIncludedFilesCount() > 0) {
    +  169  0
                         for (String s : scanner.getIncludedFiles()) {
    +  170  0
                             final File f = new File(baseDir, s);
    +  171  0
                             LOGGER.debug("Found file {}", f.toString());
    +  172  0
                             paths.add(f);
    +  173  
                         }
    -  179   +  174  
                     }
    -  180  0
                 }
    -  181  0
                 engine.scan(paths);
    +  175  0
                 }
    +  176  0
                 engine.scan(paths);
    +  177   +
     
    +  178  0
                 engine.analyzeDependencies();
    +  179  0
                 final List<Dependency> dependencies = engine.getDependencies();
    +  180  0
                 DatabaseProperties prop = null;
    +  181  0
                 CveDB cve = null;
     182   -
     
    -  183  0
                 engine.analyzeDependencies();
    -  184  0
                 final List<Dependency> dependencies = engine.getDependencies();
    -  185  0
                 DatabaseProperties prop = null;
    -  186  0
                 CveDB cve = null;
    -  187  
                 try {
    -  188  0
                     cve = new CveDB();
    -  189  0
                     cve.open();
    -  190  0
                     prop = cve.getDatabaseProperties();
    -  191  0
                 } catch (DatabaseException ex) {
    -  192  0
                     LOGGER.log(Level.FINE, "Unable to retrieve DB Properties", ex);
    -  193   +  183  0
                     cve = new CveDB();
    +  184  0
                     cve.open();
    +  185  0
                     prop = cve.getDatabaseProperties();
    +  186  0
                 } catch (DatabaseException ex) {
    +  187  0
                     LOGGER.debug("Unable to retrieve DB Properties", ex);
    +  188  
                 } finally {
    -  194  0
                     if (cve != null) {
    -  195  0
                         cve.close();
    -  196   +  189  0
                     if (cve != null) {
    +  190  0
                         cve.close();
    +  191  
                     }
    -  197   +  192  
                 }
    -  198  0
                 final ReportGenerator report = new ReportGenerator(applicationName, dependencies, engine.getAnalyzers(), prop);
    -  199   +  193  0
                 final ReportGenerator report = new ReportGenerator(applicationName, dependencies, engine.getAnalyzers(), prop);
    +  194  
                 try {
    -  200  0
                     report.generateReports(reportDirectory, outputFormat);
    -  201  0
                 } catch (IOException ex) {
    -  202  0
                     LOGGER.log(Level.SEVERE, "There was an IO error while attempting to generate the report.");
    -  203  0
                     LOGGER.log(Level.FINE, null, ex);
    -  204  0
                 } catch (Throwable ex) {
    -  205  0
                     LOGGER.log(Level.SEVERE, "There was an error while attempting to generate the report.");
    -  206  0
                     LOGGER.log(Level.FINE, null, ex);
    -  207  0
                 }
    -  208  0
             } catch (DatabaseException ex) {
    -  209  0
                 LOGGER.log(Level.SEVERE, "Unable to connect to the dependency-check database; analysis has stopped");
    -  210  0
                 LOGGER.log(Level.FINE, "", ex);
    -  211   +  195  0
                     report.generateReports(reportDirectory, outputFormat);
    +  196  0
                 } catch (IOException ex) {
    +  197  0
                     LOGGER.error("There was an IO error while attempting to generate the report.");
    +  198  0
                     LOGGER.debug("", ex);
    +  199  0
                 } catch (Throwable ex) {
    +  200  0
                     LOGGER.error("There was an error while attempting to generate the report.");
    +  201  0
                     LOGGER.debug("", ex);
    +  202  0
                 }
    +  203  0
             } catch (DatabaseException ex) {
    +  204  0
                 LOGGER.error("Unable to connect to the dependency-check database; analysis has stopped");
    +  205  0
                 LOGGER.debug("", ex);
    +  206  
             } finally {
    -  212  0
                 if (engine != null) {
    -  213  0
                     engine.cleanup();
    +  207  0
                 if (engine != null) {
    +  208  0
                     engine.cleanup();
    +  209   +
                 }
    +  210   +
             }
    +  211  0
         }
    +  212   +
     
    +  213   +
         /**
     214   -
                 }
    -  215   -
             }
    -  216  0
         }
    -  217   -
     
    -  218   -
         /**
    -  219  
          * Only executes the update phase of dependency-check.
    -  220   +  215  
          */
    -  221   +  216  
         private void runUpdateOnly() {
    -  222  0
             Engine engine = null;
    -  223   +  217  0
             Engine engine = null;
    +  218  
             try {
    -  224  0
                 engine = new Engine();
    -  225  0
                 engine.doUpdates();
    -  226  0
             } catch (DatabaseException ex) {
    -  227  0
                 LOGGER.log(Level.SEVERE, "Unable to connect to the dependency-check database; analysis has stopped");
    -  228  0
                 LOGGER.log(Level.FINE, "", ex);
    -  229   +  219  0
                 engine = new Engine();
    +  220  0
                 engine.doUpdates();
    +  221  0
             } catch (DatabaseException ex) {
    +  222  0
                 LOGGER.error("Unable to connect to the dependency-check database; analysis has stopped");
    +  223  0
                 LOGGER.debug("", ex);
    +  224  
             } finally {
    -  230  0
                 if (engine != null) {
    -  231  0
                     engine.cleanup();
    -  232   +  225  0
                 if (engine != null) {
    +  226  0
                     engine.cleanup();
    +  227  
                 }
    -  233   +  228  
             }
    -  234  0
         }
    -  235   +  229  0
         }
    +  230  
     
    -  236   +  231  
         /**
    -  237   +  232  
          * Updates the global Settings.
    -  238   +  233  
          *
    -  239   +  234  
          * @param cli a reference to the CLI Parser that contains the command line arguments used to set the corresponding settings in
    -  240   +  235  
          * the core engine.
    -  241   +  236  
          */
    -  242   +  237  
         private void populateSettings(CliParser cli) {
    -  243   +  238  
     
    -  244  0
             final boolean autoUpdate = cli.isAutoUpdate();
    -  245  0
             final String connectionTimeout = cli.getConnectionTimeout();
    -  246  0
             final String proxyServer = cli.getProxyServer();
    -  247  0
             final String proxyPort = cli.getProxyPort();
    -  248  0
             final String proxyUser = cli.getProxyUsername();
    -  249  0
             final String proxyPass = cli.getProxyPassword();
    -  250  0
             final String dataDirectory = cli.getDataDirectory();
    -  251  0
             final File propertiesFile = cli.getPropertiesFile();
    -  252  0
             final String suppressionFile = cli.getSuppressionFile();
    -  253  0
             final boolean jarDisabled = cli.isJarDisabled();
    -  254  0
             final boolean archiveDisabled = cli.isArchiveDisabled();
    -  255  0
             final boolean pyDistDisabled = cli.isPythonDistributionDisabled();
    -  256  0
             final boolean pyPkgDisabled = cli.isPythonPackageDisabled();
    -  257  0
             final boolean assemblyDisabled = cli.isAssemblyDisabled();
    -  258  0
             final boolean nuspecDisabled = cli.isNuspecDisabled();
    -  259  0
             final boolean centralDisabled = cli.isCentralDisabled();
    -  260  0
             final boolean nexusDisabled = cli.isNexusDisabled();
    -  261  0
             final String nexusUrl = cli.getNexusUrl();
    -  262  0
             final String databaseDriverName = cli.getDatabaseDriverName();
    -  263  0
             final String databaseDriverPath = cli.getDatabaseDriverPath();
    -  264  0
             final String connectionString = cli.getConnectionString();
    -  265  0
             final String databaseUser = cli.getDatabaseUser();
    -  266  0
             final String databasePassword = cli.getDatabasePassword();
    -  267  0
             final String additionalZipExtensions = cli.getAdditionalZipExtensions();
    -  268  0
             final String pathToMono = cli.getPathToMono();
    -  269   +  239  0
             final boolean autoUpdate = cli.isAutoUpdate();
    +  240  0
             final String connectionTimeout = cli.getConnectionTimeout();
    +  241  0
             final String proxyServer = cli.getProxyServer();
    +  242  0
             final String proxyPort = cli.getProxyPort();
    +  243  0
             final String proxyUser = cli.getProxyUsername();
    +  244  0
             final String proxyPass = cli.getProxyPassword();
    +  245  0
             final String dataDirectory = cli.getDataDirectory();
    +  246  0
             final File propertiesFile = cli.getPropertiesFile();
    +  247  0
             final String suppressionFile = cli.getSuppressionFile();
    +  248  0
             final boolean jarDisabled = cli.isJarDisabled();
    +  249  0
             final boolean archiveDisabled = cli.isArchiveDisabled();
    +  250  0
             final boolean pyDistDisabled = cli.isPythonDistributionDisabled();
    +  251  0
             final boolean cMakeDisabled = cli.isCmakeDisabled();
    +  252  0
             final boolean pyPkgDisabled = cli.isPythonPackageDisabled();
    +  253  0
             final boolean autoconfDisabled = cli.isAutoconfDisabled();
    +  254  0
             final boolean assemblyDisabled = cli.isAssemblyDisabled();
    +  255  0
             final boolean nuspecDisabled = cli.isNuspecDisabled();
    +  256  0
             final boolean centralDisabled = cli.isCentralDisabled();
    +  257  0
             final boolean nexusDisabled = cli.isNexusDisabled();
    +  258  0
             final String nexusUrl = cli.getNexusUrl();
    +  259  0
             final String databaseDriverName = cli.getDatabaseDriverName();
    +  260  0
             final String databaseDriverPath = cli.getDatabaseDriverPath();
    +  261  0
             final String connectionString = cli.getConnectionString();
    +  262  0
             final String databaseUser = cli.getDatabaseUser();
    +  263  0
             final String databasePassword = cli.getDatabasePassword();
    +  264  0
             final String additionalZipExtensions = cli.getAdditionalZipExtensions();
    +  265  0
             final String pathToMono = cli.getPathToMono();
    +  266  0
             final String cveMod12 = cli.getModifiedCve12Url();
    +  267  0
             final String cveMod20 = cli.getModifiedCve20Url();
    +  268  0
             final String cveBase12 = cli.getBaseCve12Url();
    +  269  0
             final String cveBase20 = cli.getBaseCve20Url();
    +  270  
     
    -  270  0
             if (propertiesFile != null) {
    -  271   +  271  0
             if (propertiesFile != null) {
    +  272  
                 try {
    -  272  0
                     Settings.mergeProperties(propertiesFile);
    -  273  0
                 } catch (FileNotFoundException ex) {
    -  274  0
                     final String msg = String.format("Unable to load properties file '%s'", propertiesFile.getPath());
    -  275  0
                     LOGGER.log(Level.SEVERE, msg);
    -  276  0
                     LOGGER.log(Level.FINE, null, ex);
    +  273  0
                     Settings.mergeProperties(propertiesFile);
    +  274  0
                 } catch (FileNotFoundException ex) {
    +  275  0
                     LOGGER.error("Unable to load properties file '{}'", propertiesFile.getPath());
    +  276  0
                     LOGGER.debug("", ex);
     277  0
                 } catch (IOException ex) {
    -  278  0
                     final String msg = String.format("Unable to find properties file '%s'", propertiesFile.getPath());
    -  279  0
                     LOGGER.log(Level.SEVERE, msg);
    -  280  0
                     LOGGER.log(Level.FINE, null, ex);
    -  281  0
                 }
    +  278  0
                     LOGGER.error("Unable to find properties file '{}'", propertiesFile.getPath());
    +  279  0
                     LOGGER.debug("", ex);
    +  280  0
                 }
    +  281   +
             }
     282   -
             }
    -  283  
             // We have to wait until we've merged the properties before attempting to set whether we use
    -  284   +  283  
             // the proxy for Nexus since it could be disabled in the properties, but not explicitly stated
    -  285   +  284  
             // on the command line
    -  286  0
             final boolean nexusUsesProxy = cli.isNexusUsesProxy();
    -  287  0
             if (dataDirectory != null) {
    -  288  0
                 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory);
    -  289  0
             } else if (System.getProperty("basedir") != null) {
    -  290  0
                 final File dataDir = new File(System.getProperty("basedir"), "data");
    -  291  0
                 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath());
    -  292  0
             } else {
    -  293  0
                 final File jarPath = new File(App.class.getProtectionDomain().getCodeSource().getLocation().getPath());
    -  294  0
                 final File base = jarPath.getParentFile();
    -  295  0
                 final String sub = Settings.getString(Settings.KEYS.DATA_DIRECTORY);
    -  296  0
                 final File dataDir = new File(base, sub);
    -  297  0
                 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath());
    -  298   +  285  0
             final boolean nexusUsesProxy = cli.isNexusUsesProxy();
    +  286  0
             if (dataDirectory != null) {
    +  287  0
                 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory);
    +  288  0
             } else if (System.getProperty("basedir") != null) {
    +  289  0
                 final File dataDir = new File(System.getProperty("basedir"), "data");
    +  290  0
                 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath());
    +  291  0
             } else {
    +  292  0
                 final File jarPath = new File(App.class.getProtectionDomain().getCodeSource().getLocation().getPath());
    +  293  0
                 final File base = jarPath.getParentFile();
    +  294  0
                 final String sub = Settings.getString(Settings.KEYS.DATA_DIRECTORY);
    +  295  0
                 final File dataDir = new File(base, sub);
    +  296  0
                 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath());
    +  297  
             }
    -  299  0
             Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate);
    -  300  0
             if (proxyServer != null && !proxyServer.isEmpty()) {
    -  301  0
                 Settings.setString(Settings.KEYS.PROXY_SERVER, proxyServer);
    -  302   +  298  0
             Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate);
    +  299  0
             if (proxyServer != null && !proxyServer.isEmpty()) {
    +  300  0
                 Settings.setString(Settings.KEYS.PROXY_SERVER, proxyServer);
    +  301  
             }
    -  303  0
             if (proxyPort != null && !proxyPort.isEmpty()) {
    -  304  0
                 Settings.setString(Settings.KEYS.PROXY_PORT, proxyPort);
    -  305   +  302  0
             if (proxyPort != null && !proxyPort.isEmpty()) {
    +  303  0
                 Settings.setString(Settings.KEYS.PROXY_PORT, proxyPort);
    +  304  
             }
    -  306  0
             if (proxyUser != null && !proxyUser.isEmpty()) {
    -  307  0
                 Settings.setString(Settings.KEYS.PROXY_USERNAME, proxyUser);
    -  308   +  305  0
             if (proxyUser != null && !proxyUser.isEmpty()) {
    +  306  0
                 Settings.setString(Settings.KEYS.PROXY_USERNAME, proxyUser);
    +  307  
             }
    -  309  0
             if (proxyPass != null && !proxyPass.isEmpty()) {
    -  310  0
                 Settings.setString(Settings.KEYS.PROXY_PASSWORD, proxyPass);
    -  311   +  308  0
             if (proxyPass != null && !proxyPass.isEmpty()) {
    +  309  0
                 Settings.setString(Settings.KEYS.PROXY_PASSWORD, proxyPass);
    +  310  
             }
    -  312  0
             if (connectionTimeout != null && !connectionTimeout.isEmpty()) {
    -  313  0
                 Settings.setString(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout);
    -  314   +  311  0
             if (connectionTimeout != null && !connectionTimeout.isEmpty()) {
    +  312  0
                 Settings.setString(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout);
    +  313   +
             }
    +  314  0
             if (suppressionFile != null && !suppressionFile.isEmpty()) {
    +  315  0
                 Settings.setString(Settings.KEYS.SUPPRESSION_FILE, suppressionFile);
    +  316  
             }
    -  315  0
             if (suppressionFile != null && !suppressionFile.isEmpty()) {
    -  316  0
                 Settings.setString(Settings.KEYS.SUPPRESSION_FILE, suppressionFile);
     317   -
             }
    +
     
     318   -
     
    -  319  
             //File Type Analyzer Settings
    -  320  0
             Settings.setBoolean(Settings.KEYS.ANALYZER_JAR_ENABLED, !jarDisabled);
    -  321  0
             Settings.setBoolean(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, !archiveDisabled);
    -  322  0
             Settings.setBoolean(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, !pyDistDisabled);
    -  323  0
             Settings.setBoolean(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, !pyPkgDisabled);
    -  324  0
             Settings.setBoolean(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, !nuspecDisabled);
    -  325  0
             Settings.setBoolean(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, !assemblyDisabled);
    -  326   +  319  0
             Settings.setBoolean(Settings.KEYS.ANALYZER_JAR_ENABLED, !jarDisabled);
    +  320  0
             Settings.setBoolean(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, !archiveDisabled);
    +  321  0
             Settings.setBoolean(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, !pyDistDisabled);
    +  322  0
             Settings.setBoolean(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, !pyPkgDisabled);
    +  323  0
             Settings.setBoolean(Settings.KEYS.ANALYZER_AUTOCONF_ENABLED, !autoconfDisabled);
    +  324  0
             Settings.setBoolean(Settings.KEYS.ANALYZER_CMAKE_ENABLED, !cMakeDisabled);
    +  325  0
             Settings.setBoolean(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, !nuspecDisabled);
    +  326  0
             Settings.setBoolean(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, !assemblyDisabled);
    +  327  0
             Settings.setBoolean(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, !cli.isOpenSSLDisabled());
    +  328  
     
    -  327  0
             Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, !centralDisabled);
    -  328  0
             Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, !nexusDisabled);
    -  329  0
             if (nexusUrl != null && !nexusUrl.isEmpty()) {
    -  330  0
                 Settings.setString(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl);
    -  331   +  329  0
             Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, !centralDisabled);
    +  330  0
             Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, !nexusDisabled);
    +  331  0
             if (nexusUrl != null && !nexusUrl.isEmpty()) {
    +  332  0
                 Settings.setString(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl);
    +  333  
             }
    -  332  0
             Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_PROXY, nexusUsesProxy);
    -  333  0
             if (databaseDriverName != null && !databaseDriverName.isEmpty()) {
    -  334  0
                 Settings.setString(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName);
    -  335   +  334  0
             Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_PROXY, nexusUsesProxy);
    +  335  0
             if (databaseDriverName != null && !databaseDriverName.isEmpty()) {
    +  336  0
                 Settings.setString(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName);
    +  337  
             }
    -  336  0
             if (databaseDriverPath != null && !databaseDriverPath.isEmpty()) {
    -  337  0
                 Settings.setString(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath);
    -  338   +  338  0
             if (databaseDriverPath != null && !databaseDriverPath.isEmpty()) {
    +  339  0
                 Settings.setString(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath);
    +  340  
             }
    -  339  0
             if (connectionString != null && !connectionString.isEmpty()) {
    -  340  0
                 Settings.setString(Settings.KEYS.DB_CONNECTION_STRING, connectionString);
    -  341   +  341  0
             if (connectionString != null && !connectionString.isEmpty()) {
    +  342  0
                 Settings.setString(Settings.KEYS.DB_CONNECTION_STRING, connectionString);
    +  343  
             }
    -  342  0
             if (databaseUser != null && !databaseUser.isEmpty()) {
    -  343  0
                 Settings.setString(Settings.KEYS.DB_USER, databaseUser);
    -  344   +  344  0
             if (databaseUser != null && !databaseUser.isEmpty()) {
    +  345  0
                 Settings.setString(Settings.KEYS.DB_USER, databaseUser);
    +  346  
             }
    -  345  0
             if (databasePassword != null && !databasePassword.isEmpty()) {
    -  346  0
                 Settings.setString(Settings.KEYS.DB_PASSWORD, databasePassword);
    -  347   +  347  0
             if (databasePassword != null && !databasePassword.isEmpty()) {
    +  348  0
                 Settings.setString(Settings.KEYS.DB_PASSWORD, databasePassword);
    +  349  
             }
    -  348  0
             if (additionalZipExtensions != null && !additionalZipExtensions.isEmpty()) {
    -  349  0
                 Settings.setString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, additionalZipExtensions);
    -  350   +  350  0
             if (additionalZipExtensions != null && !additionalZipExtensions.isEmpty()) {
    +  351  0
                 Settings.setString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, additionalZipExtensions);
    +  352  
             }
    -  351  0
             if (pathToMono != null && !pathToMono.isEmpty()) {
    -  352  0
                 Settings.setString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono);
    -  353   -
             }
    -  354  0
         }
    +  353  0
             if (pathToMono != null && !pathToMono.isEmpty()) {
    +  354  0
                 Settings.setString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono);
     355   +
             }
    +  356  0
             if (cveBase12 != null && !cveBase12.isEmpty()) {
    +  357  0
                 Settings.setString(Settings.KEYS.CVE_SCHEMA_1_2, cveBase12);
    +  358  0
                 Settings.setString(Settings.KEYS.CVE_SCHEMA_2_0, cveBase20);
    +  359  0
                 Settings.setString(Settings.KEYS.CVE_MODIFIED_12_URL, cveMod12);
    +  360  0
                 Settings.setString(Settings.KEYS.CVE_MODIFIED_20_URL, cveMod20);
    +  361   +
             }
    +  362  0
         }
    +  363   +
     
    +  364   +
         /**
    +  365   +
          * Creates a file appender and adds it to logback.
    +  366   +
          *
    +  367   +
          * @param verboseLog the path to the verbose log file
    +  368   +
          */
    +  369   +
         private void prepareLogger(String verboseLog) {
    +  370  0
             final StaticLoggerBinder loggerBinder = StaticLoggerBinder.getSingleton();
    +  371  0
             final LoggerContext context = (LoggerContext) loggerBinder.getLoggerFactory();
    +  372   +
     
    +  373  0
             final PatternLayoutEncoder encoder = new PatternLayoutEncoder();
    +  374  0
             encoder.setPattern("%d %C:%L%n%-5level - %msg%n");
    +  375  0
             encoder.setContext(context);
    +  376  0
             encoder.start();
    +  377  0
             final FileAppender fa = new FileAppender();
    +  378  0
             fa.setAppend(true);
    +  379  0
             fa.setEncoder(encoder);
    +  380  0
             fa.setContext(context);
    +  381  0
             fa.setFile(verboseLog);
    +  382  0
             final File f = new File(verboseLog);
    +  383  0
             String name = f.getName();
    +  384  0
             final int i = name.lastIndexOf('.');
    +  385  0
             if (i > 1) {
    +  386  0
                 name = name.substring(0, i);
    +  387   +
             }
    +  388  0
             fa.setName(name);
    +  389  0
             fa.start();
    +  390  0
             final ch.qos.logback.classic.Logger rootLogger = context.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME);
    +  391  0
             rootLogger.addAppender(fa);
    +  392  0
         }
    +  393   +
     
    +  394   +
         /**
    +  395   +
          * Takes a path and resolves it to be a canonical & absolute path. The caveats are that this method will take an Ant style
    +  396   +
          * file selector path (../someDir/**\/*.jar) and convert it to an absolute/canonical path (at least to the left of the first *
    +  397   +
          * or ?).
    +  398   +
          *
    +  399   +
          * @param path the path to canonicalize
    +  400   +
          * @return the canonical path
    +  401   +
          */
    +  402   +
         protected String ensureCanonicalPath(String path) {
    +  403  16
             String basePath = null;
    +  404  16
             String wildCards = null;
    +  405  16
             final String file = path.replace('\\', '/');
    +  406  16
             if (file.contains("*") || file.contains("?")) {
    +  407   +
     
    +  408  8
                 int pos = getLastFileSeparator(file);
    +  409  8
                 if (pos < 0) {
    +  410  0
                     return file;
    +  411   +
                 }
    +  412  8
                 pos += 1;
    +  413  8
                 basePath = file.substring(0, pos);
    +  414  8
                 wildCards = file.substring(pos);
    +  415  8
             } else {
    +  416  8
                 basePath = file;
    +  417   +
             }
    +  418   +
     
    +  419  16
             File f = new File(basePath);
    +  420   +
             try {
    +  421  16
                 f = f.getCanonicalFile();
    +  422  16
                 if (wildCards != null) {
    +  423  8
                     f = new File(f, wildCards);
    +  424   +
                 }
    +  425  0
             } catch (IOException ex) {
    +  426  0
                 LOGGER.warn("Invalid path '{}' was provided.", path);
    +  427  0
                 LOGGER.debug("Invalid path provided", ex);
    +  428  16
             }
    +  429  16
             return f.getAbsolutePath().replace('\\', '/');
    +  430   +
         }
    +  431   +
     
    +  432   +
         /**
    +  433   +
          * Returns the position of the last file separator.
    +  434   +
          *
    +  435   +
          * @param file a file path
    +  436   +
          * @return the position of the last file separator
    +  437   +
          */
    +  438   +
         private int getLastFileSeparator(String file) {
    +  439  8
             if (file.contains("*") || file.contains("?")) {
    +  440  8
                 int p1 = file.indexOf('*');
    +  441  8
                 int p2 = file.indexOf('?');
    +  442  8
                 p1 = p1 > 0 ? p1 : file.length();
    +  443  8
                 p2 = p2 > 0 ? p2 : file.length();
    +  444  8
                 int pos = p1 < p2 ? p1 : p2;
    +  445  8
                 pos = file.lastIndexOf('/', pos);
    +  446  8
                 return pos;
    +  447   +
             } else {
    +  448  0
                 return file.lastIndexOf('/');
    +  449   +
             }
    +  450   +
         }
    +  451  
     }
    - + diff --git a/dependency-check-cli/cobertura/org.owasp.dependencycheck.CliParser.html b/dependency-check-cli/cobertura/org.owasp.dependencycheck.CliParser.html index 276e9c305..b76c4102b 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
    61%
    103/167
    31%
    35/110
    2.149
    CliParser$ARGUMENT
    0%
    0/1
    N/A
    2.149
    CliParser
    58%
    117/200
    27%
    40/144
    2.327
    CliParser$ARGUMENT
    0%
    0/1
    N/A
    2.327
     
    @@ -61,1186 +61,1173 @@  21  
     import java.io.FileNotFoundException;
     22   -
     import java.util.logging.Logger;
    +
     
     23   -
     
    -  24  
     import org.apache.commons.cli.CommandLine;
    -  25   +  24  
     import org.apache.commons.cli.CommandLineParser;
    -  26   +  25  
     import org.apache.commons.cli.HelpFormatter;
    -  27   +  26  
     import org.apache.commons.cli.Option;
    -  28   +  27  
     import org.apache.commons.cli.OptionBuilder;
    -  29   +  28  
     import org.apache.commons.cli.OptionGroup;
    -  30   +  29  
     import org.apache.commons.cli.Options;
    -  31   +  30  
     import org.apache.commons.cli.ParseException;
    -  32   +  31  
     import org.apache.commons.cli.PosixParser;
    -  33   +  32  
     import org.owasp.dependencycheck.reporting.ReportGenerator.Format;
    -  34   +  33  
     import org.owasp.dependencycheck.utils.InvalidSettingException;
    -  35   +  34  
     import org.owasp.dependencycheck.utils.Settings;
    +  35   +
     import org.slf4j.Logger;
     36   -
     
    +
     import org.slf4j.LoggerFactory;
     37   -
     /**
    +
     
     38   -
      * A utility to parse command line arguments for the DependencyCheck.
    +
     /**
     39   -
      *
    +
      * A utility to parse command line arguments for the DependencyCheck.
     40   -
      * @author Jeremy Long
    +
      *
     41   +
      * @author Jeremy Long
    +  42  
      */
    -  42  9
     public final class CliParser {
    -  43   -
     
    +  43  72
     public final class CliParser {
     44   -
         /**
    +
     
     45   -
          * The logger.
    +
         /**
     46   +
          * The logger.
    +  47  
          */
    -  47  1
         private static final Logger LOGGER = Logger.getLogger(CliParser.class.getName());
    -  48   -
         /**
    +  48  8
         private static final Logger LOGGER = LoggerFactory.getLogger(CliParser.class);
     49   -
          * The command line.
    +
         /**
     50   -
          */
    +
          * The command line.
     51   -
         private CommandLine line;
    +
          */
     52   -
         /**
    +
         private CommandLine line;
     53   -
          * Indicates whether the arguments are valid.
    +
         /**
     54   +
          * Indicates whether the arguments are valid.
    +  55  
          */
    -  55  9
         private boolean isValid = true;
    -  56   -
     
    +  56  72
         private boolean isValid = true;
     57   -
         /**
    +
     
     58   -
          * Parses the arguments passed in and captures the results for later use.
    +
         /**
     59   -
          *
    +
          * Parses the arguments passed in and captures the results for later use.
     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  9
             line = parseArgs(args);
    -  66   -
     
    -  67  7
             if (line != null) {
    -  68  7
                 validateArgs();
    -  69   -
             }
    -  70  6
         }
    -  71   -
     
    -  72   -
         /**
    -  73   -
          * Parses the command line arguments.
    -  74   -
          *
    -  75  
          * @param args the command line arguments
    +  62   +
          * @throws FileNotFoundException is thrown when a 'file' argument does not 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  72
             line = parseArgs(args);
    +  67   +
     
    +  68  56
             if (line != null) {
    +  69  56
                 validateArgs();
    +  70   +
             }
    +  71  48
         }
    +  72   +
     
    +  73   +
         /**
    +  74   +
          * Parses the command line arguments.
    +  75   +
          *
     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 PosixParser();
    -  81  9
             final Options options = createCommandLineOptions();
    -  82  9
             return parser.parse(options, args);
    -  83   -
         }
    +  81  72
             final CommandLineParser parser = new PosixParser();
    +  82  72
             final Options options = createCommandLineOptions();
    +  83  72
             return parser.parse(options, args);
     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  7
             if (isRunScan()) {
    -  94  2
                 validatePathExists(getScanFiles(), ARGUMENT.SCAN);
    -  95  1
                 validatePathExists(getReportDirectory(), ARGUMENT.OUT);
    -  96  1
                 if (getPathToMono() != null) {
    -  97  0
                     validatePathExists(getPathToMono(), ARGUMENT.PATH_TO_MONO);
    -  98   -
                 }
    -  99  1
                 if (!line.hasOption(ARGUMENT.APP_NAME)) {
    -  100  0
                     throw new ParseException("Missing 'app' argument; the scan cannot be run without the an application name.");
    -  101   -
                 }
    -  102  1
                 if (line.hasOption(ARGUMENT.OUTPUT_FORMAT)) {
    -  103  0
                     final String format = line.getOptionValue(ARGUMENT.OUTPUT_FORMAT);
    -  104   -
                     try {
    -  105  0
                         Format.valueOf(format);
    -  106  0
                     } catch (IllegalArgumentException ex) {
    -  107  0
                         final String msg = String.format("An invalid 'format' of '%s' was specified. "
    -  108   -
                                 + "Supported output formats are XML, HTML, VULN, or ALL", format);
    -  109  0
                         throw new ParseException(msg);
    -  110  0
                     }
    -  111   -
                 }
    -  112   -
             }
    -  113  6
         }
    -  114   -
     
    -  115   -
         /**
    -  116   -
          * 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
    -  117   -
          * FileNotFoundException is thrown.
    -  118   -
          *
    -  119   -
          * @param paths the paths to validate if they exists
    -  120   -
          * @param optType the option being validated (e.g. scan, out, etc.)
    -  121   -
          * @throws FileNotFoundException is thrown if one of the paths being validated does not exist.
    -  122   -
          */
    -  123   -
         private void validatePathExists(String[] paths, String optType) throws FileNotFoundException {
    -  124  3
             for (String path : paths) {
    -  125  2
                 validatePathExists(path, optType);
    -  126   -
             }
    -  127  1
         }
    -  128   -
     
    -  129   -
         /**
    -  130   -
          * Validates whether or not the path points at a file that exists; if the path does not point to an existing file a
    -  131   -
          * FileNotFoundException is thrown.
    -  132   -
          *
    -  133   -
          * @param path the paths to validate if they exists
    -  134   -
          * @param argumentName the argument being validated (e.g. scan, out, etc.)
    -  135   -
          * @throws FileNotFoundException is thrown if the path being validated does not exist.
    -  136   -
          */
    -  137   -
         private void validatePathExists(String path, String argumentName) throws FileNotFoundException {
    -  138  3
             if (path == null) {
    -  139  0
                 isValid = false;
    -  140  0
                 final String msg = String.format("Invalid '%s' argument: null", argumentName);
    -  141  0
                 throw new FileNotFoundException(msg);
    -  142  3
             } else if (!path.contains("*") && !path.contains("?")) {
    -  143  3
                 File f = new File(path);
    -  144  3
                 if ("o".equalsIgnoreCase(argumentName.substring(0, 1)) && !"ALL".equalsIgnoreCase(this.getReportFormat())) {
    -  145  1
                     final String checkPath = path.toLowerCase();
    -  146  1
                     if (checkPath.endsWith(".html") || checkPath.endsWith(".xml") || checkPath.endsWith(".htm")) {
    -  147  0
                         if (f.getParentFile() == null) {
    -  148  0
                             f = new File(".", path);
    -  149   -
                         }
    -  150  0
                         if (!f.getParentFile().isDirectory()) {
    -  151  0
                             isValid = false;
    -  152  0
                             final String msg = String.format("Invalid '%s' argument: '%s'", argumentName, path);
    -  153  0
                             throw new FileNotFoundException(msg);
    -  154   -
                         }
    -  155   -
                     }
    -  156  1
                 } else {
    -  157  2
                     if (!f.exists()) {
    -  158  1
                         isValid = false;
    -  159  1
                         final String msg = String.format("Invalid '%s' argument: '%s'", argumentName, path);
    -  160  1
                         throw new FileNotFoundException(msg);
    -  161   -
                     }
    -  162   -
                 }
    -  163  2
             } else if (path.startsWith("//") || path.startsWith("\\\\")) {
    -  164  0
                 isValid = false;
    -  165  0
                 final String msg = String.format("Invalid '%s' argument: '%s'%nUnable to scan paths that start with '//'.", argumentName, path);
    -  166  0
                 throw new FileNotFoundException(msg);
    -  167   -
             }
    -  168  2
         }
    -  169   -
     
    -  170   -
         /**
    -  171   -
          * Generates an Options collection that is used to parse the command line and to display the help message.
    -  172   -
          *
    -  173   -
          * @return the command line options used for parsing the command line
    -  174   -
          */
    -  175   -
         @SuppressWarnings("static-access")
    -  176   -
         private Options createCommandLineOptions() {
    -  177  9
             final Options options = new Options();
    -  178  9
             addStandardOptions(options);
    -  179  9
             addAdvancedOptions(options);
    -  180  9
             addDeprecatedOptions(options);
    -  181  9
             return options;
    -  182  
         }
    -  183   +  85  
     
    -  184   +  86  
         /**
    -  185   -
          * Adds the standard command line options to the given options collection.
    -  186   +  87   +
          * Validates that the command line arguments are valid.
    +  88  
          *
    -  187   -
          * @param options a collection of command line arguments
    -  188   -
          * @throws IllegalArgumentException thrown if there is an exception
    -  189   +  89   +
          * @throws FileNotFoundException if there is a file specified by either the SCAN or CPE command line arguments that does not
    +  90   +
          * exist.
    +  91   +
          * @throws ParseException is thrown if there is an exception parsing the command line.
    +  92  
          */
    +  93   +
         private void validateArgs() throws FileNotFoundException, ParseException {
    +  94  56
             if (isRunScan()) {
    +  95  16
                 validatePathExists(getScanFiles(), ARGUMENT.SCAN);
    +  96  8
                 validatePathExists(getReportDirectory(), ARGUMENT.OUT);
    +  97  8
                 if (getPathToMono() != null) {
    +  98  0
                     validatePathExists(getPathToMono(), ARGUMENT.PATH_TO_MONO);
    +  99   +
                 }
    +  100  8
                 if (!line.hasOption(ARGUMENT.APP_NAME)) {
    +  101  0
                     throw new ParseException("Missing 'app' argument; the scan cannot be run without the an application name.");
    +  102   +
                 }
    +  103  8
                 if (line.hasOption(ARGUMENT.OUTPUT_FORMAT)) {
    +  104  0
                     final String format = line.getOptionValue(ARGUMENT.OUTPUT_FORMAT);
    +  105   +
                     try {
    +  106  0
                         Format.valueOf(format);
    +  107  0
                     } catch (IllegalArgumentException ex) {
    +  108  0
                         final String msg = String.format("An invalid 'format' of '%s' was specified. "
    +  109   +
                                 + "Supported output formats are XML, HTML, VULN, or ALL", format);
    +  110  0
                         throw new ParseException(msg);
    +  111  0
                     }
    +  112   +
                 }
    +  113  8
                 if ((getBaseCve12Url() != null || getBaseCve20Url() != null || getModifiedCve12Url() != null || getModifiedCve20Url() != null)
    +  114   +
                         && (getBaseCve12Url() == null || getBaseCve20Url() == null || getModifiedCve12Url() == null || getModifiedCve20Url() == null)) {
    +  115  0
                     final String msg = "If one of the CVE URLs is specified they must all be specified; please add the missing CVE URL.";
    +  116  0
                     throw new ParseException(msg);
    +  117   +
                 }
    +  118  8
                 if (line.hasOption((ARGUMENT.SYM_LINK_DEPTH))) {
    +  119   +
                     try {
    +  120  0
                         final int i = Integer.parseInt(line.getOptionValue(ARGUMENT.SYM_LINK_DEPTH));
    +  121  0
                         if (i < 0) {
    +  122  0
                             throw new ParseException("Symbolic Link Depth (symLink) must be greater than zero.");
    +  123   +
                         }
    +  124  0
                     } catch (NumberFormatException ex) {
    +  125  0
                         throw new ParseException("Symbolic Link Depth (symLink) is not a number.");
    +  126  0
                     }
    +  127   +
                 }
    +  128   +
             }
    +  129  48
         }
    +  130   +
     
    +  131   +
         /**
    +  132   +
          * 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
    +  133   +
          * FileNotFoundException is thrown.
    +  134   +
          *
    +  135   +
          * @param paths the paths to validate if they exists
    +  136   +
          * @param optType the option being validated (e.g. scan, out, etc.)
    +  137   +
          * @throws FileNotFoundException is thrown if one of the paths being validated does not exist.
    +  138   +
          */
    +  139   +
         private void validatePathExists(String[] paths, String optType) throws FileNotFoundException {
    +  140  24
             for (String path : paths) {
    +  141  16
                 validatePathExists(path, optType);
    +  142   +
             }
    +  143  8
         }
    +  144   +
     
    +  145   +
         /**
    +  146   +
          * Validates whether or not the path points at a file that exists; if the path does not point to an existing file a
    +  147   +
          * FileNotFoundException is thrown.
    +  148   +
          *
    +  149   +
          * @param path the paths to validate if they exists
    +  150   +
          * @param argumentName the argument being validated (e.g. scan, out, etc.)
    +  151   +
          * @throws FileNotFoundException is thrown if the path being validated does not exist.
    +  152   +
          */
    +  153   +
         private void validatePathExists(String path, String argumentName) throws FileNotFoundException {
    +  154  24
             if (path == null) {
    +  155  0
                 isValid = false;
    +  156  0
                 final String msg = String.format("Invalid '%s' argument: null", argumentName);
    +  157  0
                 throw new FileNotFoundException(msg);
    +  158  24
             } else if (!path.contains("*") && !path.contains("?")) {
    +  159  24
                 File f = new File(path);
    +  160  24
                 if ("o".equalsIgnoreCase(argumentName.substring(0, 1)) && !"ALL".equalsIgnoreCase(this.getReportFormat())) {
    +  161  8
                     final String checkPath = path.toLowerCase();
    +  162  8
                     if (checkPath.endsWith(".html") || checkPath.endsWith(".xml") || checkPath.endsWith(".htm")) {
    +  163  0
                         if (f.getParentFile() == null) {
    +  164  0
                             f = new File(".", path);
    +  165   +
                         }
    +  166  0
                         if (!f.getParentFile().isDirectory()) {
    +  167  0
                             isValid = false;
    +  168  0
                             final String msg = String.format("Invalid '%s' argument: '%s'", argumentName, path);
    +  169  0
                             throw new FileNotFoundException(msg);
    +  170   +
                         }
    +  171   +
                     }
    +  172  8
                 } else {
    +  173  16
                     if (!f.exists()) {
    +  174  8
                         isValid = false;
    +  175  8
                         final String msg = String.format("Invalid '%s' argument: '%s'", argumentName, path);
    +  176  8
                         throw new FileNotFoundException(msg);
    +  177   +
                     }
    +  178   +
                 }
    +  179  16
             } else if (path.startsWith("//") || path.startsWith("\\\\")) {
    +  180  0
                 isValid = false;
    +  181  0
                 final String msg = String.format("Invalid '%s' argument: '%s'%nUnable to scan paths that start with '//'.", argumentName, path);
    +  182  0
                 throw new FileNotFoundException(msg);
    +  183   +
             }
    +  184  16
         }
    +  185   +
     
    +  186   +
         /**
    +  187   +
          * Generates an Options collection that is used to parse the command line and to display the help message.
    +  188   +
          *
    +  189   +
          * @return the command line options used for parsing the command line
     190   -
         @SuppressWarnings("static-access")
    +
          */
     191   -
         private void addStandardOptions(final Options options) throws IllegalArgumentException {
    -  192  11
             final Option help = new Option(ARGUMENT.HELP_SHORT, ARGUMENT.HELP, false,
    -  193   -
                     "Print this message.");
    -  194   -
     
    -  195  11
             final Option advancedHelp = OptionBuilder.withLongOpt(ARGUMENT.ADVANCED_HELP)
    -  196   -
                     .withDescription("Print the advanced help message.").create();
    -  197   -
     
    -  198  11
             final Option version = new Option(ARGUMENT.VERSION_SHORT, ARGUMENT.VERSION,
    +
         @SuppressWarnings("static-access")
    +  192   +
         private Options createCommandLineOptions() {
    +  193  72
             final Options options = new Options();
    +  194  72
             addStandardOptions(options);
    +  195  72
             addAdvancedOptions(options);
    +  196  72
             addDeprecatedOptions(options);
    +  197  72
             return options;
    +  198   +
         }
     199   -
                     false, "Print the version information.");
    +
     
     200   -
     
    -  201  11
             final Option noUpdate = new Option(ARGUMENT.DISABLE_AUTO_UPDATE_SHORT, ARGUMENT.DISABLE_AUTO_UPDATE,
    +
         /**
    +  201   +
          * Adds the standard command line options to the given options collection.
     202   -
                     false, "Disables the automatic updating of the CPE data.");
    +
          *
     203   -
     
    -  204  11
             final Option appName = OptionBuilder.withArgName("name").hasArg().withLongOpt(ARGUMENT.APP_NAME)
    +
          * @param options a collection of command line arguments
    +  204   +
          * @throws IllegalArgumentException thrown if there is an exception
     205   -
                     .withDescription("The name of the application being scanned. This is a required argument.")
    +
          */
     206   -
                     .create(ARGUMENT.APP_NAME_SHORT);
    +
         @SuppressWarnings("static-access")
     207   -
     
    -  208  11
             final Option path = OptionBuilder.withArgName("path").hasArg().withLongOpt(ARGUMENT.SCAN)
    +
         private void addStandardOptions(final Options options) throws IllegalArgumentException {
    +  208  88
             final Option help = new Option(ARGUMENT.HELP_SHORT, ARGUMENT.HELP, false,
     209   -
                     .withDescription("The path to scan - this option can be specified multiple times. Ant style"
    +
                     "Print this message.");
     210   -
                             + " paths are supported (e.g. path/**/*.jar).")
    -  211   -
                     .create(ARGUMENT.SCAN_SHORT);
    +
     
    +  211  88
             final Option advancedHelp = OptionBuilder.withLongOpt(ARGUMENT.ADVANCED_HELP)
     212   +
                     .withDescription("Print the advanced help message.").create();
    +  213  
     
    -  213  11
             final Option excludes = OptionBuilder.withArgName("pattern").hasArg().withLongOpt(ARGUMENT.EXCLUDE)
    -  214   -
                     .withDescription("Specify and exclusion pattern. This option can be specified multiple times"
    +  214  88
             final Option version = new Option(ARGUMENT.VERSION_SHORT, ARGUMENT.VERSION,
     215   -
                             + " and it accepts Ant style excludsions.")
    +
                     false, "Print the version information.");
     216   -
                     .create();
    -  217  
     
    -  218  11
             final Option props = OptionBuilder.withArgName("file").hasArg().withLongOpt(ARGUMENT.PROP)
    +  217  88
             final Option noUpdate = new Option(ARGUMENT.DISABLE_AUTO_UPDATE_SHORT, ARGUMENT.DISABLE_AUTO_UPDATE,
    +  218   +
                     false, "Disables the automatic updating of the CPE data.");
     219   -
                     .withDescription("A property file to load.")
    -  220   -
                     .create(ARGUMENT.PROP_SHORT);
    +
     
    +  220  88
             final Option appName = OptionBuilder.withArgName("name").hasArg().withLongOpt(ARGUMENT.APP_NAME)
     221   -
     
    -  222  11
             final Option out = OptionBuilder.withArgName("path").hasArg().withLongOpt(ARGUMENT.OUT)
    +
                     .withDescription("The name of the application being scanned. This is a required argument.")
    +  222   +
                     .create(ARGUMENT.APP_NAME_SHORT);
     223   -
                     .withDescription("The folder to write reports to. This defaults to the current directory. "
    -  224   -
                             + "It is possible to set this to a specific file name if the format argument is not set to ALL.")
    +
     
    +  224  88
             final Option path = OptionBuilder.withArgName("path").hasArg().withLongOpt(ARGUMENT.SCAN)
     225   -
                     .create(ARGUMENT.OUT_SHORT);
    +
                     .withDescription("The path to scan - this option can be specified multiple times. Ant style"
     226   -
     
    -  227  11
             final Option outputFormat = OptionBuilder.withArgName("format").hasArg().withLongOpt(ARGUMENT.OUTPUT_FORMAT)
    +
                             + " paths are supported (e.g. path/**/*.jar).")
    +  227   +
                     .create(ARGUMENT.SCAN_SHORT);
     228   -
                     .withDescription("The output format to write to (XML, HTML, VULN, ALL). The default is HTML.")
    -  229   -
                     .create(ARGUMENT.OUTPUT_FORMAT_SHORT);
    +
     
    +  229  88
             final Option excludes = OptionBuilder.withArgName("pattern").hasArg().withLongOpt(ARGUMENT.EXCLUDE)
     230   -
     
    -  231  11
             final Option verboseLog = OptionBuilder.withArgName("file").hasArg().withLongOpt(ARGUMENT.VERBOSE_LOG)
    +
                     .withDescription("Specify and exclusion pattern. This option can be specified multiple times"
    +  231   +
                             + " and it accepts Ant style excludsions.")
     232   -
                     .withDescription("The file path to write verbose logging information.")
    -  233   -
                     .create(ARGUMENT.VERBOSE_LOG_SHORT);
    -  234   -
     
    -  235  11
             final Option suppressionFile = OptionBuilder.withArgName("file").hasArg().withLongOpt(ARGUMENT.SUPPRESSION_FILE)
    -  236   -
                     .withDescription("The file path to the suppression XML file.")
    -  237  
                     .create();
    -  238   +  233  
     
    +  234  88
             final Option props = OptionBuilder.withArgName("file").hasArg().withLongOpt(ARGUMENT.PROP)
    +  235   +
                     .withDescription("A property file to load.")
    +  236   +
                     .create(ARGUMENT.PROP_SHORT);
    +  237   +
     
    +  238  88
             final Option out = OptionBuilder.withArgName("path").hasArg().withLongOpt(ARGUMENT.OUT)
     239   -
             //This is an option group because it can be specified more then once.
    -  240  11
             final OptionGroup og = new OptionGroup();
    -  241  11
             og.addOption(path);
    +
                     .withDescription("The folder to write reports to. This defaults to the current directory. "
    +  240   +
                             + "It is possible to set this to a specific file name if the format argument is not set to ALL.")
    +  241   +
                     .create(ARGUMENT.OUT_SHORT);
     242  
     
    -  243  11
             final OptionGroup exog = new OptionGroup();
    -  244  11
             exog.addOption(excludes);
    +  243  88
             final Option outputFormat = OptionBuilder.withArgName("format").hasArg().withLongOpt(ARGUMENT.OUTPUT_FORMAT)
    +  244   +
                     .withDescription("The output format to write to (XML, HTML, VULN, ALL). The default is HTML.")
     245   +
                     .create(ARGUMENT.OUTPUT_FORMAT_SHORT);
    +  246  
     
    -  246  11
             options.addOptionGroup(og)
    -  247   -
                     .addOptionGroup(exog)
    +  247  88
             final Option verboseLog = OptionBuilder.withArgName("file").hasArg().withLongOpt(ARGUMENT.VERBOSE_LOG)
     248   -
                     .addOption(out)
    +
                     .withDescription("The file path to write verbose logging information.")
     249   -
                     .addOption(outputFormat)
    +
                     .create(ARGUMENT.VERBOSE_LOG_SHORT);
     250   -
                     .addOption(appName)
    -  251   -
                     .addOption(version)
    +
     
    +  251  88
             final Option symLinkDepth = OptionBuilder.withArgName("depth").hasArg().withLongOpt(ARGUMENT.SYM_LINK_DEPTH)
     252   -
                     .addOption(help)
    +
                     .withDescription("Sets how deep nested symbolic links will be followed; 0 indicates symbolic links will not be followed.")
     253   -
                     .addOption(advancedHelp)
    +
                     .create();
     254   -
                     .addOption(noUpdate)
    -  255   -
                     .addOption(props)
    +
     
    +  255  88
             final Option suppressionFile = OptionBuilder.withArgName("file").hasArg().withLongOpt(ARGUMENT.SUPPRESSION_FILE)
     256   -
                     .addOption(verboseLog)
    +
                     .withDescription("The file path to the suppression XML file.")
     257   -
                     .addOption(suppressionFile);
    -  258  11
         }
    +
                     .create();
    +  258   +
     
     259   -
     
    -  260   -
         /**
    -  261   -
          * Adds the advanced command line options to the given options collection. These are split out for purposes of being able to
    +
             //This is an option group because it can be specified more then once.
    +  260  88
             final OptionGroup og = new OptionGroup();
    +  261  88
             og.addOption(path);
     262   -
          * display two different help messages.
    -  263   -
          *
    -  264   -
          * @param options a collection of command line arguments
    +
     
    +  263  88
             final OptionGroup exog = new OptionGroup();
    +  264  88
             exog.addOption(excludes);
     265   -
          * @throws IllegalArgumentException thrown if there is an exception
    -  266   -
          */
    +
     
    +  266  88
             options.addOptionGroup(og)
     267   -
         @SuppressWarnings("static-access")
    +
                     .addOptionGroup(exog)
     268   -
         private void addAdvancedOptions(final Options options) throws IllegalArgumentException {
    +
                     .addOption(out)
     269   -
     
    -  270  9
             final Option updateOnly = OptionBuilder.withLongOpt(ARGUMENT.UPDATE_ONLY)
    +
                     .addOption(outputFormat)
    +  270   +
                     .addOption(appName)
     271   -
                     .withDescription("Only update the local NVD data cache; no scan will be executed.").create();
    +
                     .addOption(version)
     272   -
     
    -  273  9
             final Option data = OptionBuilder.withArgName("path").hasArg().withLongOpt(ARGUMENT.DATA_DIRECTORY)
    +
                     .addOption(help)
    +  273   +
                     .addOption(advancedHelp)
     274   -
                     .withDescription("The location of the H2 Database file. This option should generally not be set.")
    +
                     .addOption(noUpdate)
     275   -
                     .create(ARGUMENT.DATA_DIRECTORY_SHORT);
    +
                     .addOption(symLinkDepth)
     276   -
     
    -  277  9
             final Option connectionTimeout = OptionBuilder.withArgName("timeout").hasArg().withLongOpt(ARGUMENT.CONNECTION_TIMEOUT)
    +
                     .addOption(props)
    +  277   +
                     .addOption(verboseLog)
     278   -
                     .withDescription("The connection timeout (in milliseconds) to use when downloading resources.")
    -  279   -
                     .create(ARGUMENT.CONNECTION_TIMEOUT_SHORT);
    +
                     .addOption(suppressionFile);
    +  279  88
         }
     280  
     
    -  281  9
             final Option proxyServer = OptionBuilder.withArgName("server").hasArg().withLongOpt(ARGUMENT.PROXY_SERVER)
    +  281   +
         /**
     282   -
                     .withDescription("The proxy server to use when downloading resources.")
    +
          * Adds the advanced command line options to the given options collection. These are split out for purposes of being able to
     283   -
                     .create();
    +
          * display two different help messages.
     284   -
     
    -  285  9
             final Option proxyPort = OptionBuilder.withArgName("port").hasArg().withLongOpt(ARGUMENT.PROXY_PORT)
    +
          *
    +  285   +
          * @param options a collection of command line arguments
     286   -
                     .withDescription("The proxy port to use when downloading resources.")
    +
          * @throws IllegalArgumentException thrown if there is an exception
     287   -
                     .create();
    +
          */
     288   -
     
    -  289  9
             final Option proxyUsername = OptionBuilder.withArgName("user").hasArg().withLongOpt(ARGUMENT.PROXY_USERNAME)
    +
         @SuppressWarnings("static-access")
    +  289   +
         private void addAdvancedOptions(final Options options) throws IllegalArgumentException {
     290   -
                     .withDescription("The proxy username to use when downloading resources.")
    -  291   -
                     .create();
    +
     
    +  291  72
             final Option cve12Base = OptionBuilder.withArgName("url").hasArg().withLongOpt(ARGUMENT.CVE_BASE_12)
     292   -
     
    -  293  9
             final Option proxyPassword = OptionBuilder.withArgName("pass").hasArg().withLongOpt(ARGUMENT.PROXY_PASSWORD)
    +
                     .withDescription("Base URL for each year’s CVE 1.2, the %d will be replaced with the year. ")
    +  293   +
                     .create();
     294   -
                     .withDescription("The proxy password to use when downloading resources.")
    -  295   -
                     .create();
    +
     
    +  295  72
             final Option cve20Base = OptionBuilder.withArgName("url").hasArg().withLongOpt(ARGUMENT.CVE_BASE_20)
     296   -
     
    -  297  9
             final Option connectionString = OptionBuilder.withArgName("connStr").hasArg().withLongOpt(ARGUMENT.CONNECTION_STRING)
    +
                     .withDescription("Base URL for each year’s CVE 2.0, the %d will be replaced with the year.")
    +  297   +
                     .create();
     298   -
                     .withDescription("The connection string to the database.")
    -  299   -
                     .create();
    +
     
    +  299  72
             final Option cve12Modified = OptionBuilder.withArgName("url").hasArg().withLongOpt(ARGUMENT.CVE_MOD_12)
     300   -
     
    -  301  9
             final Option dbUser = OptionBuilder.withArgName("user").hasArg().withLongOpt(ARGUMENT.DB_NAME)
    +
                     .withDescription("URL for the modified CVE 1.2.")
    +  301   +
                     .create();
     302   -
                     .withDescription("The username used to connect to the database.")
    -  303   -
                     .create();
    +
     
    +  303  72
             final Option cve20Modified = OptionBuilder.withArgName("url").hasArg().withLongOpt(ARGUMENT.CVE_MOD_20)
     304   -
     
    -  305  9
             final Option dbPassword = OptionBuilder.withArgName("password").hasArg().withLongOpt(ARGUMENT.DB_PASSWORD)
    +
                     .withDescription("URL for the modified CVE 2.0.")
    +  305   +
                     .create();
     306   -
                     .withDescription("The password for connecting to the database.")
    -  307   -
                     .create();
    +
     
    +  307  72
             final Option updateOnly = OptionBuilder.withLongOpt(ARGUMENT.UPDATE_ONLY)
     308   +
                     .withDescription("Only update the local NVD data cache; no scan will be executed.").create();
    +  309  
     
    -  309  9
             final Option dbDriver = OptionBuilder.withArgName("driver").hasArg().withLongOpt(ARGUMENT.DB_DRIVER)
    -  310   -
                     .withDescription("The database driver name.")
    +  310  72
             final Option data = OptionBuilder.withArgName("path").hasArg().withLongOpt(ARGUMENT.DATA_DIRECTORY)
     311   -
                     .create();
    +
                     .withDescription("The location of the H2 Database file. This option should generally not be set.")
     312   +
                     .create(ARGUMENT.DATA_DIRECTORY_SHORT);
    +  313  
     
    -  313  9
             final Option dbDriverPath = OptionBuilder.withArgName("path").hasArg().withLongOpt(ARGUMENT.DB_DRIVER_PATH)
    -  314   -
                     .withDescription("The path to the database driver; note, this does not need to be set unless the JAR is outside of the classpath.")
    +  314  72
             final Option nexusUrl = OptionBuilder.withArgName("url").hasArg().withLongOpt(ARGUMENT.NEXUS_URL)
     315   -
                     .create();
    +
                     .withDescription("The url to the Nexus Server's REST API Endpoint (http://domain/nexus/service/local). "
     316   +
                             + "If not set the Nexus Analyzer will be disabled.").create();
    +  317  
     
    -  317  9
             final Option disableJarAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_JAR)
    -  318   -
                     .withDescription("Disable the Jar Analyzer.")
    +  318  72
             final Option nexusUsesProxy = OptionBuilder.withArgName("true/false").hasArg().withLongOpt(ARGUMENT.NEXUS_USES_PROXY)
     319   +
                     .withDescription("Whether or not the configured proxy should be used when connecting to Nexus.")
    +  320  
                     .create();
    -  320  9
             final Option disableArchiveAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_ARCHIVE)
     321   -
                     .withDescription("Disable the Archive Analyzer.")
    -  322   -
                     .create();
    -  323  9
             final Option disableNuspecAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_NUSPEC)
    +
     
    +  322  72
             final Option additionalZipExtensions = OptionBuilder.withArgName("extensions").hasArg()
    +  323   +
                     .withLongOpt(ARGUMENT.ADDITIONAL_ZIP_EXTENSIONS)
     324   -
                     .withDescription("Disable the Nuspec Analyzer.")
    +
                     .withDescription("A comma separated list of additional extensions to be scanned as ZIP files "
     325   -
                     .create();
    +
                             + "(ZIP, EAR, WAR are already treated as zip files)").create();
     326  
     
    -  327  9
             final Option disableAssemblyAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_ASSEMBLY)
    +  327  72
             final Option pathToMono = OptionBuilder.withArgName("path").hasArg().withLongOpt(ARGUMENT.PATH_TO_MONO)
     328   -
                     .withDescription("Disable the .NET Assembly Analyzer.")
    +
                     .withDescription("The path to Mono for .NET Assembly analysis on non-windows systems.")
     329  
                     .create();
     330  
     
    -  331  9
             final Option disablePythonDistributionAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_PY_DIST)
    +  331  72
             final Option connectionTimeout = OptionBuilder.withArgName("timeout").hasArg().withLongOpt(ARGUMENT.CONNECTION_TIMEOUT)
     332   -
                     .withDescription("Disable the Python Distribution Analyzer.").create();
    +
                     .withDescription("The connection timeout (in milliseconds) to use when downloading resources.")
     333   +
                     .create(ARGUMENT.CONNECTION_TIMEOUT_SHORT);
    +  334  
     
    -  334  9
             final Option disablePythonPackageAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_PY_PKG)
    -  335   -
                     .withDescription("Disable the Python Package Analyzer.").create();
    +  335  72
             final Option proxyServer = OptionBuilder.withArgName("server").hasArg().withLongOpt(ARGUMENT.PROXY_SERVER)
     336   +
                     .withDescription("The proxy server to use when downloading resources.").create();
    +  337  
     
    -  337  9
             final Option disableCentralAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_CENTRAL)
    -  338   -
                     .withDescription("Disable the Central Analyzer. If this analyzer is disabled it is likely you also want to disable "
    +  338  72
             final Option proxyPort = OptionBuilder.withArgName("port").hasArg().withLongOpt(ARGUMENT.PROXY_PORT)
     339   -
                             + "the Nexus Analyzer.")
    +
                     .withDescription("The proxy port to use when downloading resources.").create();
     340   -
                     .create();
    -  341  
     
    -  342  9
             final Option disableNexusAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_NEXUS)
    +  341  72
             final Option proxyUsername = OptionBuilder.withArgName("user").hasArg().withLongOpt(ARGUMENT.PROXY_USERNAME)
    +  342   +
                     .withDescription("The proxy username to use when downloading resources.").create();
     343   -
                     .withDescription("Disable the Nexus Analyzer.")
    -  344   -
                     .create();
    +
     
    +  344  72
             final Option proxyPassword = OptionBuilder.withArgName("pass").hasArg().withLongOpt(ARGUMENT.PROXY_PASSWORD)
     345   +
                     .withDescription("The proxy password to use when downloading resources.").create();
    +  346  
     
    -  346  9
             final Option nexusUrl = OptionBuilder.withArgName("url").hasArg().withLongOpt(ARGUMENT.NEXUS_URL)
    -  347   -
                     .withDescription("The url to the Nexus Server's REST API Endpoint (http://domain/nexus/service/local). "
    +  347  72
             final Option connectionString = OptionBuilder.withArgName("connStr").hasArg().withLongOpt(ARGUMENT.CONNECTION_STRING)
     348   -
                             + "If not set the Nexus Analyzer will be disabled.")
    +
                     .withDescription("The connection string to the database.").create();
     349   -
                     .create();
    -  350  
     
    -  351  9
             final Option nexusUsesProxy = OptionBuilder.withArgName("true/false").hasArg().withLongOpt(ARGUMENT.NEXUS_USES_PROXY)
    +  350  72
             final Option dbUser = OptionBuilder.withArgName("user").hasArg().withLongOpt(ARGUMENT.DB_NAME)
    +  351   +
                     .withDescription("The username used to connect to the database.").create();
     352   -
                     .withDescription("Whether or not the configured proxy should be used when connecting to Nexus.")
    -  353   -
                     .create();
    +
     
    +  353  72
             final Option dbPassword = OptionBuilder.withArgName("password").hasArg().withLongOpt(ARGUMENT.DB_PASSWORD)
     354   +
                     .withDescription("The password for connecting to the database.").create();
    +  355  
     
    -  355  9
             final Option additionalZipExtensions = OptionBuilder.withArgName("extensions").hasArg()
    -  356   -
                     .withLongOpt(ARGUMENT.ADDITIONAL_ZIP_EXTENSIONS)
    +  356  72
             final Option dbDriver = OptionBuilder.withArgName("driver").hasArg().withLongOpt(ARGUMENT.DB_DRIVER)
     357   -
                     .withDescription("A comma separated list of additional extensions to be scanned as ZIP files "
    +
                     .withDescription("The database driver name.").create();
     358   -
                             + "(ZIP, EAR, WAR are already treated as zip files)")
    -  359   -
                     .create();
    +
     
    +  359  72
             final Option dbDriverPath = OptionBuilder.withArgName("path").hasArg().withLongOpt(ARGUMENT.DB_DRIVER_PATH)
     360   -
     
    -  361  9
             final Option pathToMono = OptionBuilder.withArgName("path").hasArg().withLongOpt(ARGUMENT.PATH_TO_MONO)
    +
                     .withDescription("The path to the database driver; note, this does not need to be set unless the JAR is outside of the classpath.")
    +  361   +
                     .create();
     362   -
                     .withDescription("The path to Mono for .NET Assembly analysis on non-windows systems.")
    -  363   -
                     .create();
    +
     
    +  363  72
             final Option disableJarAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_JAR)
     364   +
                     .withDescription("Disable the Jar Analyzer.").create();
    +  365  
     
    -  365  9
             options.addOption(updateOnly)
    -  366   -
                     .addOption(proxyPort)
    +  366  72
             final Option disableArchiveAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_ARCHIVE)
     367   -
                     .addOption(proxyServer)
    +
                     .withDescription("Disable the Archive Analyzer.").create();
     368   -
                     .addOption(proxyUsername)
    -  369   -
                     .addOption(proxyPassword)
    +
     
    +  369  72
             final Option disableNuspecAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_NUSPEC)
     370   -
                     .addOption(connectionTimeout)
    +
                     .withDescription("Disable the Nuspec Analyzer.").create();
     371   -
                     .addOption(connectionString)
    -  372   -
                     .addOption(dbUser)
    +
     
    +  372  72
             final Option disableAssemblyAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_ASSEMBLY)
     373   -
                     .addOption(data)
    +
                     .withDescription("Disable the .NET Assembly Analyzer.").create();
     374   -
                     .addOption(dbPassword)
    -  375   -
                     .addOption(dbDriver)
    +
     
    +  375  72
             final Option disablePythonDistributionAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_PY_DIST)
     376   -
                     .addOption(dbDriverPath)
    +
                     .withDescription("Disable the Python Distribution Analyzer.").create();
     377   -
                     .addOption(disableJarAnalyzer)
    -  378   -
                     .addOption(disableArchiveAnalyzer)
    +
     
    +  378  72
             final Option disablePythonPackageAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_PY_PKG)
     379   -
                     .addOption(disableAssemblyAnalyzer)
    +
                     .withDescription("Disable the Python Package Analyzer.").create();
     380   -
                     .addOption(disablePythonDistributionAnalyzer)
    -  381   -
                     .addOption(disablePythonPackageAnalyzer)
    +
     
    +  381  72
             final Option disableAutoconfAnalyzer = OptionBuilder
     382   -
                     .addOption(disableNuspecAnalyzer)
    +
                     .withLongOpt(ARGUMENT.DISABLE_AUTOCONF)
     383   -
                     .addOption(disableCentralAnalyzer)
    +
                     .withDescription("Disable the Autoconf Analyzer.").create();
     384   -
                     .addOption(disableNexusAnalyzer)
    -  385   -
                     .addOption(nexusUrl)
    +
     
    +  385  72
             final Option disableOpenSSLAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_OPENSSL)
     386   -
                     .addOption(nexusUsesProxy)
    -  387   -
                     .addOption(additionalZipExtensions)
    +
                     .withDescription("Disable the OpenSSL Analyzer.").create();
    +  387  72
             final Option disableCmakeAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_CMAKE).
     388   -
                     .addOption(pathToMono);
    -  389  9
         }
    -  390   +
                     withDescription("Disable the Cmake Analyzer.").create();
    +  389  
     
    +  390  72
             final Option disableCentralAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_CENTRAL)
     391   -
         /**
    +
                     .withDescription("Disable the Central Analyzer. If this analyzer is disabled it is likely you also want to disable "
     392   -
          * Adds the deprecated command line options to the given options collection. These are split out for purposes of not including
    +
                             + "the Nexus Analyzer.").create();
     393   -
          * them in the help message. We need to add the deprecated options so as not to break existing scripts.
    -  394   -
          *
    +
     
    +  394  72
             final Option disableNexusAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_NEXUS)
     395   -
          * @param options a collection of command line arguments
    +
                     .withDescription("Disable the Nexus Analyzer.").create();
     396   -
          * @throws IllegalArgumentException thrown if there is an exception
    -  397   -
          */
    +
     
    +  397  72
             options.addOption(updateOnly)
     398   -
         @SuppressWarnings("static-access")
    +
                     .addOption(cve12Base)
     399   -
         private void addDeprecatedOptions(final Options options) throws IllegalArgumentException {
    +
                     .addOption(cve20Base)
     400   -
     
    -  401  9
             final Option proxyServer = OptionBuilder.withArgName("url").hasArg().withLongOpt(ARGUMENT.PROXY_URL)
    +
                     .addOption(cve12Modified)
    +  401   +
                     .addOption(cve20Modified)
     402   -
                     .withDescription("The proxy url argument is deprecated, use proxyserver instead.")
    +
                     .addOption(proxyPort)
     403   -
                     .create();
    +
                     .addOption(proxyServer)
     404   -
     
    -  405  9
             options.addOption(proxyServer);
    -  406  9
         }
    +
                     .addOption(proxyUsername)
    +  405   +
                     .addOption(proxyPassword)
    +  406   +
                     .addOption(connectionTimeout)
     407   -
     
    +
                     .addOption(connectionString)
     408   -
         /**
    +
                     .addOption(dbUser)
     409   -
          * Determines if the 'version' command line argument was passed in.
    +
                     .addOption(data)
     410   -
          *
    +
                     .addOption(dbPassword)
     411   -
          * @return whether or not the 'version' command line argument was passed in
    +
                     .addOption(dbDriver)
     412   -
          */
    +
                     .addOption(dbDriverPath)
     413   -
         public boolean isGetVersion() {
    -  414  7
             return (line != null) && line.hasOption(ARGUMENT.VERSION);
    +
                     .addOption(disableJarAnalyzer)
    +  414   +
                     .addOption(disableArchiveAnalyzer)
     415   -
         }
    +
                     .addOption(disableAssemblyAnalyzer)
     416   -
     
    +
                     .addOption(disablePythonDistributionAnalyzer)
     417   -
         /**
    +
                     .addOption(disableCmakeAnalyzer)
     418   -
          * Determines if the 'help' command line argument was passed in.
    +
                     .addOption(disablePythonPackageAnalyzer)
     419   -
          *
    +
                     .addOption(disableAutoconfAnalyzer)
     420   -
          * @return whether or not the 'help' command line argument was passed in
    +
                     .addOption(disableOpenSSLAnalyzer)
     421   -
          */
    +
                     .addOption(disableNuspecAnalyzer)
     422   -
         public boolean isGetHelp() {
    -  423  7
             return (line != null) && line.hasOption(ARGUMENT.HELP);
    +
                     .addOption(disableCentralAnalyzer)
    +  423   +
                     .addOption(disableNexusAnalyzer)
     424   -
         }
    +
                     .addOption(nexusUrl)
     425   -
     
    +
                     .addOption(nexusUsesProxy)
     426   -
         /**
    +
                     .addOption(additionalZipExtensions)
     427   -
          * Determines if the 'scan' command line argument was passed in.
    -  428   -
          *
    +
                     .addOption(pathToMono);
    +  428  72
         }
     429   -
          * @return whether or not the 'scan' command line argument was passed in
    -  430   -
          */
    -  431   -
         public boolean isRunScan() {
    -  432  14
             return (line != null) && isValid && line.hasOption(ARGUMENT.SCAN);
    -  433   -
         }
    -  434  
     
    -  435   +  430  
         /**
    -  436   -
          * Returns true if the disableJar command line argument was specified.
    -  437   +  431   +
          * Adds the deprecated command line options to the given options collection. These are split out for purposes of not including
    +  432   +
          * them in the help message. We need to add the deprecated options so as not to break existing scripts.
    +  433  
          *
    -  438   -
          * @return true if the disableJar command line argument was specified; otherwise false
    -  439   +  434   +
          * @param options a collection of command line arguments
    +  435   +
          * @throws IllegalArgumentException thrown if there is an exception
    +  436  
          */
    -  440   -
         public boolean isJarDisabled() {
    -  441  0
             return (line != null) && line.hasOption(ARGUMENT.DISABLE_JAR);
    +  437   +
         @SuppressWarnings({"static-access", "deprecation"})
    +  438   +
         private void addDeprecatedOptions(final Options options) throws IllegalArgumentException {
    +  439   +
     
    +  440  72
             final Option proxyServer = OptionBuilder.withArgName("url").hasArg().withLongOpt(ARGUMENT.PROXY_URL)
    +  441   +
                     .withDescription("The proxy url argument is deprecated, use proxyserver instead.")
     442   -
         }
    +
                     .create();
     443  
     
    -  444   -
         /**
    -  445   -
          * Returns true if the disableArchive command line argument was specified.
    +  444  72
             options.addOption(proxyServer);
    +  445  72
         }
     446   -
          *
    +
     
     447   -
          * @return true if the disableArchive command line argument was specified; otherwise false
    +
         /**
     448   -
          */
    +
          * Determines if the 'version' command line argument was passed in.
     449   -
         public boolean isArchiveDisabled() {
    -  450  0
             return (line != null) && line.hasOption(ARGUMENT.DISABLE_ARCHIVE);
    +
          *
    +  450   +
          * @return whether or not the 'version' command line argument was passed in
     451   -
         }
    +
          */
     452   -
     
    -  453   -
         /**
    +
         public boolean isGetVersion() {
    +  453  56
             return (line != null) && line.hasOption(ARGUMENT.VERSION);
     454   -
          * Returns true if the disableNuspec command line argument was specified.
    +
         }
     455   -
          *
    +
     
     456   -
          * @return true if the disableNuspec command line argument was specified; otherwise false
    +
         /**
     457   -
          */
    +
          * Determines if the 'help' command line argument was passed in.
     458   -
         public boolean isNuspecDisabled() {
    -  459  0
             return (line != null) && line.hasOption(ARGUMENT.DISABLE_NUSPEC);
    +
          *
    +  459   +
          * @return whether or not the 'help' command line argument was passed in
     460   -
         }
    +
          */
     461   -
     
    -  462   -
         /**
    +
         public boolean isGetHelp() {
    +  462  56
             return (line != null) && line.hasOption(ARGUMENT.HELP);
     463   -
          * Returns true if the disableAssembly command line argument was specified.
    +
         }
     464   -
          *
    +
     
     465   -
          * @return true if the disableAssembly command line argument was specified; otherwise false
    +
         /**
     466   -
          */
    +
          * Determines if the 'scan' command line argument was passed in.
     467   -
         public boolean isAssemblyDisabled() {
    -  468  0
             return (line != null) && line.hasOption(ARGUMENT.DISABLE_ASSEMBLY);
    +
          *
    +  468   +
          * @return whether or not the 'scan' command line argument was passed in
     469   -
         }
    +
          */
     470   -
     
    -  471   -
         /**
    +
         public boolean isRunScan() {
    +  471  112
             return (line != null) && isValid && line.hasOption(ARGUMENT.SCAN);
     472   -
          * Returns true if the disablePyDist command line argument was specified.
    +
         }
     473   -
          *
    +
     
     474   -
          * @return true if the disablePyDist command line argument was specified; otherwise false
    +
         /**
     475   -
          */
    +
          * Returns the symbolic link depth (how deeply symbolic links will be followed).
     476   -
         public boolean isPythonDistributionDisabled() {
    -  477  0
             return (line != null) && line.hasOption(ARGUMENT.DISABLE_PY_DIST);
    +
          *
    +  477   +
          * @return the symbolic link depth
     478   -
         }
    +
          */
     479   -
     
    -  480   -
         /**
    +
         public int getSymLinkDepth() {
    +  480  0
             int value = 0;
     481   -
          * Returns true if the disablePyPkg command line argument was specified.
    -  482   -
          *
    -  483   -
          * @return true if the disablePyPkg command line argument was specified; otherwise false
    -  484   -
          */
    +
             try {
    +  482  0
                 value = Integer.parseInt(line.getOptionValue(ARGUMENT.SYM_LINK_DEPTH, "0"));
    +  483  0
                 if (value < 0) {
    +  484  0
                     value = 0;
     485   -
         public boolean isPythonPackageDisabled() {
    -  486  0
             return (line != null) && line.hasOption(ARGUMENT.DISABLE_PY_PKG);
    -  487   -
         }
    -  488   -
     
    -  489   -
         /**
    -  490   -
          * Returns true if the disableNexus command line argument was specified.
    -  491   -
          *
    -  492   -
          * @return true if the disableNexus command line argument was specified; otherwise false
    -  493   -
          */
    -  494   -
         public boolean isNexusDisabled() {
    -  495  0
             return (line != null) && line.hasOption(ARGUMENT.DISABLE_NEXUS);
    -  496   -
         }
    -  497   -
     
    -  498   -
         /**
    -  499   -
          * Returns true if the disableCentral command line argument was specified.
    -  500   -
          *
    -  501   -
          * @return true if the disableCentral command line argument was specified; otherwise false
    -  502   -
          */
    -  503   -
         public boolean isCentralDisabled() {
    -  504  0
             return (line != null) && line.hasOption(ARGUMENT.DISABLE_CENTRAL);
    -  505   -
         }
    -  506   -
     
    -  507   -
         /**
    -  508   -
          * Returns the url to the nexus server if one was specified.
    -  509   -
          *
    -  510   -
          * @return the url to the nexus server; if none was specified this will return null;
    -  511   -
          */
    -  512   -
         public String getNexusUrl() {
    -  513  0
             if (line == null || !line.hasOption(ARGUMENT.NEXUS_URL)) {
    -  514  0
                 return null;
    -  515   -
             } else {
    -  516  0
                 return line.getOptionValue(ARGUMENT.NEXUS_URL);
    -  517   -
             }
    -  518   -
         }
    -  519   -
     
    -  520   -
         /**
    -  521   -
          * Returns true if the Nexus Analyzer should use the configured proxy to connect to Nexus; otherwise false is returned.
    -  522   -
          *
    -  523   -
          * @return true if the Nexus Analyzer should use the configured proxy to connect to Nexus; otherwise false
    -  524   -
          */
    -  525   -
         public boolean isNexusUsesProxy() {
    -  526   -
             // If they didn't specify whether Nexus needs to use the proxy, we should
    -  527   -
             // still honor the property if it's set.
    -  528  0
             if (line == null || !line.hasOption(ARGUMENT.NEXUS_USES_PROXY)) {
    -  529   -
                 try {
    -  530  0
                     return Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_PROXY);
    -  531  0
                 } catch (InvalidSettingException ise) {
    -  532  0
                     return true;
    -  533  
                 }
    -  534   -
             } else {
    -  535  0
                 return Boolean.parseBoolean(line.getOptionValue(ARGUMENT.NEXUS_USES_PROXY));
    -  536   -
             }
    -  537   +  486  0
             } catch (NumberFormatException ex) {
    +  487  0
                 LOGGER.debug("Symbolic link was not a number");
    +  488  0
             }
    +  489  0
             return value;
    +  490  
         }
    -  538   +  491  
     
    -  539   +  492  
         /**
    +  493   +
          * Returns true if the disableJar command line argument was specified.
    +  494   +
          *
    +  495   +
          * @return true if the disableJar command line argument was specified; otherwise false
    +  496   +
          */
    +  497   +
         public boolean isJarDisabled() {
    +  498  0
             return (line != null) && line.hasOption(ARGUMENT.DISABLE_JAR);
    +  499   +
         }
    +  500   +
     
    +  501   +
         /**
    +  502   +
          * Returns true if the disableArchive command line argument was specified.
    +  503   +
          *
    +  504   +
          * @return true if the disableArchive command line argument was specified; otherwise false
    +  505   +
          */
    +  506   +
         public boolean isArchiveDisabled() {
    +  507  0
             return (line != null) && line.hasOption(ARGUMENT.DISABLE_ARCHIVE);
    +  508   +
         }
    +  509   +
     
    +  510   +
         /**
    +  511   +
          * Returns true if the disableNuspec command line argument was specified.
    +  512   +
          *
    +  513   +
          * @return true if the disableNuspec command line argument was specified; otherwise false
    +  514   +
          */
    +  515   +
         public boolean isNuspecDisabled() {
    +  516  0
             return (line != null) && line.hasOption(ARGUMENT.DISABLE_NUSPEC);
    +  517   +
         }
    +  518   +
     
    +  519   +
         /**
    +  520   +
          * Returns true if the disableAssembly command line argument was specified.
    +  521   +
          *
    +  522   +
          * @return true if the disableAssembly command line argument was specified; otherwise false
    +  523   +
          */
    +  524   +
         public boolean isAssemblyDisabled() {
    +  525  0
             return (line != null) && line.hasOption(ARGUMENT.DISABLE_ASSEMBLY);
    +  526   +
         }
    +  527   +
     
    +  528   +
         /**
    +  529   +
          * Returns true if the disablePyDist command line argument was specified.
    +  530   +
          *
    +  531   +
          * @return true if the disablePyDist command line argument was specified; otherwise false
    +  532   +
          */
    +  533   +
         public boolean isPythonDistributionDisabled() {
    +  534  0
             return (line != null) && line.hasOption(ARGUMENT.DISABLE_PY_DIST);
    +  535   +
         }
    +  536   +
     
    +  537   +
         /**
    +  538   +
          * Returns true if the disablePyPkg command line argument was specified.
    +  539   +
          *
     540   -
          * Displays the command line help message to the standard output.
    +
          * @return true if the disablePyPkg command line argument was specified; otherwise false
     541  
          */
     542   -
         public void printHelp() {
    -  543  2
             final HelpFormatter formatter = new HelpFormatter();
    -  544  2
             final Options options = new Options();
    -  545  2
             addStandardOptions(options);
    -  546  2
             if (line != null && line.hasOption(ARGUMENT.ADVANCED_HELP)) {
    -  547  0
                 addAdvancedOptions(options);
    +
         public boolean isPythonPackageDisabled() {
    +  543  0
             return (line != null) && line.hasOption(ARGUMENT.DISABLE_PY_PKG);
    +  544   +
         }
    +  545   +
     
    +  546   +
         /**
    +  547   +
          * Returns true if the disableCmake command line argument was specified.
     548   -
             }
    -  549  2
             final String helpMsg = String.format("%n%s"
    +
          *
    +  549   +
          * @return true if the disableCmake command line argument was specified; otherwise false
     550   -
                     + " can be used to identify if there are any known CVE vulnerabilities in libraries utilized by an application. "
    +
          */
     551   -
                     + "%s will automatically update required data from the Internet, such as the CVE and CPE data files from nvd.nist.gov.%n%n",
    -  552   -
                     Settings.getString("application.name", "DependencyCheck"),
    +
         public boolean isCmakeDisabled() {
    +  552  0
             return (line != null) && line.hasOption(ARGUMENT.DISABLE_CMAKE);
     553   -
                     Settings.getString("application.name", "DependencyCheck"));
    +
         }
     554  
     
    -  555  2
             formatter.printHelp(Settings.getString("application.name", "DependencyCheck"),
    +  555   +
         /**
     556   -
                     helpMsg,
    +
          * Returns true if the disableAutoconf command line argument was specified.
     557   -
                     options,
    +
          *
     558   -
                     "",
    +
          * @return true if the disableAutoconf command line argument was specified; otherwise false
     559   -
                     true);
    -  560  2
         }
    -  561   -
     
    +
          */
    +  560   +
         public boolean isAutoconfDisabled() {
    +  561  0
             return (line != null) && line.hasOption(ARGUMENT.DISABLE_AUTOCONF);
     562   -
         /**
    +
         }
     563   -
          * Retrieves the file command line parameter(s) specified for the 'scan' argument.
    +
     
     564   -
          *
    +
         /**
     565   -
          * @return the file paths specified on the command line for scan
    +
          * Returns true if the disableNexus command line argument was specified.
     566   -
          */
    +
          *
     567   -
         public String[] getScanFiles() {
    -  568  3
             return line.getOptionValues(ARGUMENT.SCAN);
    +
          * @return true if the disableNexus command line argument was specified; otherwise false
    +  568   +
          */
     569   -
         }
    -  570   -
     
    +
         public boolean isNexusDisabled() {
    +  570  0
             return (line != null) && line.hasOption(ARGUMENT.DISABLE_NEXUS);
     571   -
         /**
    +
         }
     572   -
          * Retrieves the list of excluded file patterns specified by the 'exclude' argument.
    +
     
     573   -
          *
    +
         /**
     574   -
          * @return the excluded file patterns
    +
          * Returns true if the disableOpenSSL command line argument was specified.
     575   -
          */
    +
          *
     576   -
         public String[] getExcludeList() {
    -  577  0
             return line.getOptionValues(ARGUMENT.EXCLUDE);
    +
          * @return true if the disableOpenSSL command line argument was specified; otherwise false
    +  577   +
          */
     578   -
         }
    -  579   -
     
    +
         public boolean isOpenSSLDisabled() {
    +  579  0
             return (line != null) && line.hasOption(ARGUMENT.DISABLE_OPENSSL);
     580   -
         /**
    +
         }
     581   -
          * Returns the directory to write the reports to specified on the command line.
    +
     
     582   -
          *
    +
         /**
     583   -
          * @return the path to the reports directory.
    +
          * Returns true if the disableCentral command line argument was specified.
     584   -
          */
    +
          *
     585   -
         public String getReportDirectory() {
    -  586  1
             return line.getOptionValue(ARGUMENT.OUT, ".");
    +
          * @return true if the disableCentral command line argument was specified; otherwise false
    +  586   +
          */
     587   -
         }
    -  588   -
     
    +
         public boolean isCentralDisabled() {
    +  588  0
             return (line != null) && line.hasOption(ARGUMENT.DISABLE_CENTRAL);
     589   -
         /**
    +
         }
     590   -
          * Returns the path to Mono for .NET Assembly analysis on non-windows systems.
    +
     
     591   -
          *
    +
         /**
     592   -
          * @return the path to Mono
    +
          * Returns the url to the nexus server if one was specified.
     593   -
          */
    +
          *
     594   -
         public String getPathToMono() {
    -  595  1
             return line.getOptionValue(ARGUMENT.PATH_TO_MONO);
    +
          * @return the url to the nexus server; if none was specified this will return null;
    +  595   +
          */
     596   -
         }
    -  597   -
     
    -  598   -
         /**
    +
         public String getNexusUrl() {
    +  597  0
             if (line == null || !line.hasOption(ARGUMENT.NEXUS_URL)) {
    +  598  0
                 return null;
     599   -
          * Returns the output format specified on the command line. Defaults to HTML if no format was specified.
    -  600   -
          *
    +
             } else {
    +  600  0
                 return line.getOptionValue(ARGUMENT.NEXUS_URL);
     601   -
          * @return the output format name.
    +
             }
     602   -
          */
    +
         }
     603   -
         public String getReportFormat() {
    -  604  1
             return line.getOptionValue(ARGUMENT.OUTPUT_FORMAT, "HTML");
    +
     
    +  604   +
         /**
     605   -
         }
    +
          * Returns true if the Nexus Analyzer should use the configured proxy to connect to Nexus; otherwise false is returned.
     606   -
     
    +
          *
     607   -
         /**
    +
          * @return true if the Nexus Analyzer should use the configured proxy to connect to Nexus; otherwise false
     608   -
          * Returns the application name specified on the command line.
    +
          */
     609   -
          *
    +
         public boolean isNexusUsesProxy() {
     610   -
          * @return the application name.
    +
             // If they didn't specify whether Nexus needs to use the proxy, we should
     611   -
          */
    -  612   -
         public String getApplicationName() {
    -  613  0
             return line.getOptionValue(ARGUMENT.APP_NAME);
    -  614   -
         }
    -  615   -
     
    -  616   -
         /**
    +
             // still honor the property if it's set.
    +  612  0
             if (line == null || !line.hasOption(ARGUMENT.NEXUS_USES_PROXY)) {
    +  613   +
                 try {
    +  614  0
                     return Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_PROXY);
    +  615  0
                 } catch (InvalidSettingException ise) {
    +  616  0
                     return true;
     617   -
          * Returns the connection timeout.
    -  618   -
          *
    -  619   -
          * @return the connection timeout
    -  620   -
          */
    -  621   -
         public String getConnectionTimeout() {
    -  622  0
             return line.getOptionValue(ARGUMENT.CONNECTION_TIMEOUT);
    -  623   -
         }
    -  624   -
     
    -  625   -
         /**
    -  626   -
          * Returns the proxy server.
    -  627   -
          *
    -  628   -
          * @return the proxy server
    -  629   -
          */
    -  630   -
         public String getProxyServer() {
    -  631   -
     
    -  632  0
             String server = line.getOptionValue(ARGUMENT.PROXY_SERVER);
    -  633  0
             if (server == null) {
    -  634  0
                 server = line.getOptionValue(ARGUMENT.PROXY_URL);
    -  635  0
                 if (server != null) {
    -  636  0
                     LOGGER.warning("An old command line argument 'proxyurl' was detected; use proxyserver instead");
    -  637  
                 }
    +  618   +
             } else {
    +  619  0
                 return Boolean.parseBoolean(line.getOptionValue(ARGUMENT.NEXUS_USES_PROXY));
    +  620   +
             }
    +  621   +
         }
    +  622   +
     
    +  623   +
         /**
    +  624   +
          * Displays the command line help message to the standard output.
    +  625   +
          */
    +  626   +
         public void printHelp() {
    +  627  16
             final HelpFormatter formatter = new HelpFormatter();
    +  628  16
             final Options options = new Options();
    +  629  16
             addStandardOptions(options);
    +  630  16
             if (line != null && line.hasOption(ARGUMENT.ADVANCED_HELP)) {
    +  631  0
                 addAdvancedOptions(options);
    +  632   +
             }
    +  633  16
             final String helpMsg = String.format("%n%s"
    +  634   +
                     + " can be used to identify if there are any known CVE vulnerabilities in libraries utilized by an application. "
    +  635   +
                     + "%s will automatically update required data from the Internet, such as the CVE and CPE data files from nvd.nist.gov.%n%n",
    +  636   +
                     Settings.getString("application.name", "DependencyCheck"),
    +  637   +
                     Settings.getString("application.name", "DependencyCheck"));
     638   -
             }
    -  639  0
             return server;
    +
     
    +  639  16
             formatter.printHelp(Settings.getString("application.name", "DependencyCheck"),
     640   -
         }
    +
                     helpMsg,
     641   -
     
    +
                     options,
     642   -
         /**
    +
                     "",
     643   -
          * Returns the proxy port.
    -  644   -
          *
    +
                     true);
    +  644  16
         }
     645   -
          * @return the proxy port
    +
     
     646   -
          */
    +
         /**
     647   -
         public String getProxyPort() {
    -  648  0
             return line.getOptionValue(ARGUMENT.PROXY_PORT);
    +
          * Retrieves the file command line parameter(s) specified for the 'scan' argument.
    +  648   +
          *
     649   -
         }
    +
          * @return the file paths specified on the command line for scan
     650   -
     
    +
          */
     651   -
         /**
    -  652   -
          * Returns the proxy username.
    +
         public String[] getScanFiles() {
    +  652  24
             return line.getOptionValues(ARGUMENT.SCAN);
     653   -
          *
    +
         }
     654   -
          * @return the proxy username
    +
     
     655   -
          */
    +
         /**
     656   -
         public String getProxyUsername() {
    -  657  0
             return line.getOptionValue(ARGUMENT.PROXY_USERNAME);
    +
          * Retrieves the list of excluded file patterns specified by the 'exclude' argument.
    +  657   +
          *
     658   -
         }
    +
          * @return the excluded file patterns
     659   -
     
    +
          */
     660   -
         /**
    -  661   -
          * Returns the proxy password.
    +
         public String[] getExcludeList() {
    +  661  0
             return line.getOptionValues(ARGUMENT.EXCLUDE);
     662   -
          *
    +
         }
     663   -
          * @return the proxy password
    +
     
     664   -
          */
    +
         /**
     665   -
         public String getProxyPassword() {
    -  666  0
             return line.getOptionValue(ARGUMENT.PROXY_PASSWORD);
    +
          * Returns the directory to write the reports to specified on the command line.
    +  666   +
          *
     667   -
         }
    +
          * @return the path to the reports directory.
     668   -
     
    +
          */
     669   -
         /**
    -  670   -
          * Get the value of dataDirectory.
    +
         public String getReportDirectory() {
    +  670  8
             return line.getOptionValue(ARGUMENT.OUT, ".");
     671   -
          *
    -  672   -
          * @return the value of dataDirectory
    -  673   -
          */
    -  674   -
         public String getDataDirectory() {
    -  675  0
             return line.getOptionValue(ARGUMENT.DATA_DIRECTORY);
    -  676  
         }
    -  677   +  672  
     
    -  678   +  673  
         /**
    -  679   -
          * Returns the properties file specified on the command line.
    -  680   +  674   +
          * Returns the path to Mono for .NET Assembly analysis on non-windows systems.
    +  675  
          *
    -  681   -
          * @return the properties file specified on the command line
    -  682   +  676   +
          * @return the path to Mono
    +  677  
          */
    +  678   +
         public String getPathToMono() {
    +  679  8
             return line.getOptionValue(ARGUMENT.PATH_TO_MONO);
    +  680   +
         }
    +  681   +
     
    +  682   +
         /**
     683   -
         public File getPropertiesFile() {
    -  684  0
             final String path = line.getOptionValue(ARGUMENT.PROP);
    -  685  0
             if (path != null) {
    -  686  0
                 return new File(path);
    +
          * Returns the output format specified on the command line. Defaults to HTML if no format was specified.
    +  684   +
          *
    +  685   +
          * @return the output format name.
    +  686   +
          */
     687   -
             }
    -  688  0
             return null;
    +
         public String getReportFormat() {
    +  688  8
             return line.getOptionValue(ARGUMENT.OUTPUT_FORMAT, "HTML");
     689  
         }
     690   @@ -1248,16 +1235,16 @@  691  
         /**
     692   -
          * Returns the path to the verbose log file.
    +
          * Returns the application name specified on the command line.
     693  
          *
     694   -
          * @return the path to the verbose log file
    +
          * @return the application name.
     695  
          */
     696   -
         public String getVerboseLog() {
    -  697  0
             return line.getOptionValue(ARGUMENT.VERBOSE_LOG);
    +
         public String getApplicationName() {
    +  697  0
             return line.getOptionValue(ARGUMENT.APP_NAME);
     698  
         }
     699   @@ -1265,16 +1252,16 @@  700  
         /**
     701   -
          * Returns the path to the suppression file.
    +
          * Returns the base URL for the CVE 1.2 XMl file.
     702  
          *
     703   -
          * @return the path to the suppression file
    +
          * @return the URL to the CVE 1.2 XML file.
     704  
          */
     705   -
         public String getSuppressionFile() {
    -  706  0
             return line.getOptionValue(ARGUMENT.SUPPRESSION_FILE);
    +
         public String getBaseCve12Url() {
    +  706  8
             return line.getOptionValue(ARGUMENT.CVE_BASE_12);
     707  
         }
     708   @@ -1282,567 +1269,855 @@  709  
         /**
     710   -
          * <p>
    +
          * Returns the base URL for the CVE 2.0 XMl file.
     711   -
          * Prints the manifest information to standard output.</p>
    +
          *
     712   -
          * <ul><li>Implementation-Title: ${pom.name}</li>
    +
          * @return the URL to the CVE 2.0 XML file.
     713   -
          * <li>Implementation-Version: ${pom.version}</li></ul>
    +
          */
     714   -
          */
    -  715   -
         public void printVersionInfo() {
    -  716  1
             final String version = String.format("%s version %s",
    +
         public String getBaseCve20Url() {
    +  715  8
             return line.getOptionValue(ARGUMENT.CVE_BASE_20);
    +  716   +
         }
     717   -
                     Settings.getString(Settings.KEYS.APPLICATION_VAME, "dependency-check"),
    +
     
     718   -
                     Settings.getString(Settings.KEYS.APPLICATION_VERSION, "Unknown"));
    -  719  1
             System.out.println(version);
    -  720  1
         }
    +
         /**
    +  719   +
          * Returns the URL for the modified CVE 1.2 XMl file.
    +  720   +
          *
     721   -
     
    +
          * @return the URL to the modified CVE 1.2 XML file.
     722   -
         /**
    +
          */
     723   -
          * Checks if the auto update feature has been disabled. If it has been disabled via the command line this will return false.
    -  724   -
          *
    +
         public String getModifiedCve12Url() {
    +  724  8
             return line.getOptionValue(ARGUMENT.CVE_MOD_12);
     725   -
          * @return <code>true</code> if auto-update is allowed; otherwise <code>false</code>
    +
         }
     726   -
          */
    +
     
     727   -
         public boolean isAutoUpdate() {
    -  728  0
             return (line == null) || !line.hasOption(ARGUMENT.DISABLE_AUTO_UPDATE);
    +
         /**
    +  728   +
          * Returns the URL for the modified CVE 2.0 XMl file.
     729   -
         }
    +
          *
     730   -
     
    +
          * @return the URL to the modified CVE 2.0 XML file.
     731   -
         /**
    +
          */
     732   -
          * Checks if the update only flag has been set.
    -  733   -
          *
    +
         public String getModifiedCve20Url() {
    +  733  8
             return line.getOptionValue(ARGUMENT.CVE_MOD_20);
     734   -
          * @return <code>true</code> if the update only flag has been set; otherwise <code>false</code>.
    +
         }
     735   -
          */
    +
     
     736   -
         public boolean isUpdateOnly() {
    -  737  0
             return (line == null) || line.hasOption(ARGUMENT.UPDATE_ONLY);
    +
         /**
    +  737   +
          * Returns the connection timeout.
     738   -
         }
    +
          *
     739   -
     
    +
          * @return the connection timeout
     740   -
         /**
    +
          */
     741   -
          * Returns the database driver name if specified; otherwise null is returned.
    -  742   -
          *
    +
         public String getConnectionTimeout() {
    +  742  0
             return line.getOptionValue(ARGUMENT.CONNECTION_TIMEOUT);
     743   -
          * @return the database driver name if specified; otherwise null is returned
    +
         }
     744   -
          */
    +
     
     745   -
         public String getDatabaseDriverName() {
    -  746  0
             return line.getOptionValue(ARGUMENT.DB_DRIVER);
    +
         /**
    +  746   +
          * Returns the proxy server.
     747   -
         }
    +
          *
     748   -
     
    +
          * @return the proxy server
     749   -
         /**
    +
          */
     750   -
          * Returns the database driver path if specified; otherwise null is returned.
    +
         @SuppressWarnings("deprecation")
     751   -
          *
    +
         public String getProxyServer() {
     752   -
          * @return the database driver name if specified; otherwise null is returned
    -  753   -
          */
    -  754   -
         public String getDatabaseDriverPath() {
    -  755  0
             return line.getOptionValue(ARGUMENT.DB_DRIVER_PATH);
    -  756   -
         }
    -  757  
     
    +  753  0
             String server = line.getOptionValue(ARGUMENT.PROXY_SERVER);
    +  754  0
             if (server == null) {
    +  755  0
                 server = line.getOptionValue(ARGUMENT.PROXY_URL);
    +  756  0
                 if (server != null) {
    +  757  0
                     LOGGER.warn("An old command line argument 'proxyurl' was detected; use proxyserver instead");
     758   -
         /**
    +
                 }
     759   -
          * Returns the database connection string if specified; otherwise null is returned.
    -  760   -
          *
    +
             }
    +  760  0
             return server;
     761   -
          * @return the database connection string if specified; otherwise null is returned
    +
         }
     762   -
          */
    +
     
     763   -
         public String getConnectionString() {
    -  764  0
             return line.getOptionValue(ARGUMENT.CONNECTION_STRING);
    +
         /**
    +  764   +
          * Returns the proxy port.
     765   -
         }
    +
          *
     766   -
     
    +
          * @return the proxy port
     767   -
         /**
    +
          */
     768   -
          * Returns the database database user name if specified; otherwise null is returned.
    -  769   -
          *
    +
         public String getProxyPort() {
    +  769  0
             return line.getOptionValue(ARGUMENT.PROXY_PORT);
     770   -
          * @return the database database user name if specified; otherwise null is returned
    +
         }
     771   -
          */
    +
     
     772   -
         public String getDatabaseUser() {
    -  773  0
             return line.getOptionValue(ARGUMENT.DB_NAME);
    +
         /**
    +  773   +
          * Returns the proxy username.
     774   -
         }
    +
          *
     775   -
     
    +
          * @return the proxy username
     776   -
         /**
    +
          */
     777   -
          * Returns the database database password if specified; otherwise null is returned.
    -  778   -
          *
    +
         public String getProxyUsername() {
    +  778  0
             return line.getOptionValue(ARGUMENT.PROXY_USERNAME);
     779   -
          * @return the database database password if specified; otherwise null is returned
    +
         }
     780   -
          */
    +
     
     781   -
         public String getDatabasePassword() {
    -  782  0
             return line.getOptionValue(ARGUMENT.DB_PASSWORD);
    +
         /**
    +  782   +
          * Returns the proxy password.
     783   -
         }
    -  784   -
     
    -  785   -
         /**
    -  786   -
          * Returns the additional Extensions if specified; otherwise null is returned.
    -  787  
          *
    +  784   +
          * @return the proxy password
    +  785   +
          */
    +  786   +
         public String getProxyPassword() {
    +  787  0
             return line.getOptionValue(ARGUMENT.PROXY_PASSWORD);
     788   -
          * @return the additional Extensions; otherwise null is returned
    -  789   -
          */
    -  790   -
         public String getAdditionalZipExtensions() {
    -  791  0
             return line.getOptionValue(ARGUMENT.ADDITIONAL_ZIP_EXTENSIONS);
    -  792  
         }
    -  793   +  789  
     
    -  794   +  790  
         /**
    -  795   -
          * A collection of static final strings that represent the possible command line arguments.
    -  796   +  791   +
          * Get the value of dataDirectory.
    +  792   +
          *
    +  793   +
          * @return the value of dataDirectory
    +  794  
          */
    -  797  9
         public static class ARGUMENT {
    +  795   +
         public String getDataDirectory() {
    +  796  0
             return line.getOptionValue(ARGUMENT.DATA_DIRECTORY);
    +  797   +
         }
     798  
     
     799   -
             /**
    +
         /**
     800   -
              * The long CLI argument name specifying the directory/file to scan.
    +
          * Returns the properties file specified on the command line.
     801   -
              */
    +
          *
     802   -
             public static final String SCAN = "scan";
    +
          * @return the properties file specified on the command line
     803   -
             /**
    +
          */
     804   -
              * The short CLI argument name specifying the directory/file to scan.
    -  805   -
              */
    -  806   -
             public static final String SCAN_SHORT = "s";
    -  807   -
             /**
    +
         public File getPropertiesFile() {
    +  805  0
             final String path = line.getOptionValue(ARGUMENT.PROP);
    +  806  0
             if (path != null) {
    +  807  0
                 return new File(path);
     808   -
              * The long CLI argument name specifying that the CPE/CVE/etc. data should not be automatically updated.
    -  809   -
              */
    +
             }
    +  809  0
             return null;
     810   -
             public static final String DISABLE_AUTO_UPDATE = "noupdate";
    -  811   -
             /**
    -  812   -
              * The short CLI argument name specifying that the CPE/CVE/etc. data should not be automatically updated.
    -  813   -
              */
    -  814   -
             public static final String DISABLE_AUTO_UPDATE_SHORT = "n";
    -  815   -
             /**
    -  816   -
              * The long CLI argument name specifying that only the update phase should be executed; no scan should be run.
    -  817   -
              */
    -  818   -
             public static final String UPDATE_ONLY = "updateonly";
    -  819   -
             /**
    -  820   -
              * The long CLI argument name specifying the directory to write the reports to.
    -  821   -
              */
    -  822   -
             public static final String OUT = "out";
    -  823   -
             /**
    -  824   -
              * The short CLI argument name specifying the directory to write the reports to.
    -  825   -
              */
    -  826   -
             public static final String OUT_SHORT = "o";
    -  827   -
             /**
    -  828   -
              * The long CLI argument name specifying the output format to write the reports to.
    -  829   -
              */
    -  830   -
             public static final String OUTPUT_FORMAT = "format";
    -  831   -
             /**
    -  832   -
              * The short CLI argument name specifying the output format to write the reports to.
    -  833   -
              */
    -  834   -
             public static final String OUTPUT_FORMAT_SHORT = "f";
    -  835   -
             /**
    -  836   -
              * The long CLI argument name specifying the name of the application to be scanned.
    -  837   -
              */
    -  838   -
             public static final String APP_NAME = "app";
    -  839   -
             /**
    -  840   -
              * The short CLI argument name specifying the name of the application to be scanned.
    -  841   -
              */
    -  842   -
             public static final String APP_NAME_SHORT = "a";
    -  843   -
             /**
    -  844   -
              * The long CLI argument name asking for help.
    -  845   -
              */
    -  846   -
             public static final String HELP = "help";
    -  847   -
             /**
    -  848   -
              * The long CLI argument name asking for advanced help.
    -  849   -
              */
    -  850   -
             public static final String ADVANCED_HELP = "advancedHelp";
    -  851   -
             /**
    -  852   -
              * The short CLI argument name asking for help.
    -  853   -
              */
    -  854   -
             public static final String HELP_SHORT = "h";
    -  855   -
             /**
    -  856   -
              * The long CLI argument name asking for the version.
    -  857   -
              */
    -  858   -
             public static final String VERSION_SHORT = "v";
    -  859   -
             /**
    -  860   -
              * The short CLI argument name asking for the version.
    -  861   -
              */
    -  862   -
             public static final String VERSION = "version";
    -  863   -
             /**
    -  864   -
              * The CLI argument name indicating the proxy port.
    -  865   -
              */
    -  866   -
             public static final String PROXY_PORT = "proxyport";
    -  867   -
             /**
    -  868   -
              * The CLI argument name indicating the proxy server.
    -  869   -
              */
    -  870   -
             public static final String PROXY_SERVER = "proxyserver";
    -  871   -
             /**
    -  872   -
              * The CLI argument name indicating the proxy url.
    -  873   -
              *
    -  874   -
              * @deprecated use {@link org.owasp.dependencycheck.cli.CliParser.ArgumentName#PROXY_SERVER} instead
    -  875   -
              */
    -  876   -
             @Deprecated
    -  877   -
             public static final String PROXY_URL = "proxyurl";
    -  878   -
             /**
    -  879   -
              * The CLI argument name indicating the proxy username.
    -  880   -
              */
    -  881   -
             public static final String PROXY_USERNAME = "proxyuser";
    -  882   -
             /**
    -  883   -
              * The CLI argument name indicating the proxy password.
    -  884   -
              */
    -  885   -
             public static final String PROXY_PASSWORD = "proxypass";
    -  886   -
             /**
    -  887   -
              * The short CLI argument name indicating the connection timeout.
    -  888   -
              */
    -  889   -
             public static final String CONNECTION_TIMEOUT_SHORT = "c";
    -  890   -
             /**
    -  891   -
              * The CLI argument name indicating the connection timeout.
    -  892   -
              */
    -  893   -
             public static final String CONNECTION_TIMEOUT = "connectiontimeout";
    -  894   -
             /**
    -  895   -
              * The short CLI argument name for setting the location of an additional properties file.
    -  896   -
              */
    -  897   -
             public static final String PROP_SHORT = "P";
    -  898   -
             /**
    -  899   -
              * The CLI argument name for setting the location of an additional properties file.
    -  900   -
              */
    -  901   -
             public static final String PROP = "propertyfile";
    -  902   -
             /**
    -  903   -
              * The CLI argument name for setting the location of the data directory.
    -  904   -
              */
    -  905   -
             public static final String DATA_DIRECTORY = "data";
    -  906   -
             /**
    -  907   -
              * The short CLI argument name for setting the location of the data directory.
    -  908   -
              */
    -  909   -
             public static final String DATA_DIRECTORY_SHORT = "d";
    -  910   -
             /**
    -  911   -
              * The CLI argument name for setting the location of the data directory.
    -  912   -
              */
    -  913   -
             public static final String VERBOSE_LOG = "log";
    -  914   -
             /**
    -  915   -
              * The short CLI argument name for setting the location of the data directory.
    -  916   -
              */
    -  917   -
             public static final String VERBOSE_LOG_SHORT = "l";
    -  918   -
             /**
    -  919   -
              * The CLI argument name for setting the location of the suppression file.
    -  920   -
              */
    -  921   -
             public static final String SUPPRESSION_FILE = "suppression";
    -  922   -
             /**
    -  923   -
              * Disables the Jar Analyzer.
    -  924   -
              */
    -  925   -
             public static final String DISABLE_JAR = "disableJar";
    -  926   -
             /**
    -  927   -
              * Disables the Archive Analyzer.
    -  928   -
              */
    -  929   -
             public static final String DISABLE_ARCHIVE = "disableArchive";
    -  930   -
             /**
    -  931   -
              * Disables the Python Distribution Analyzer.
    -  932   -
              */
    -  933   -
             public static final String DISABLE_PY_DIST = "disablePyDist";
    -  934   -
             /**
    -  935   -
              * Disables the Python Package Analyzer.
    -  936   -
              */
    -  937   -
             public static final String DISABLE_PY_PKG = "disablePyPkg";
    -  938   -
             /**
    -  939   -
              * Disables the Assembly Analyzer.
    -  940   -
              */
    -  941   -
             public static final String DISABLE_ASSEMBLY = "disableAssembly";
    -  942   -
             /**
    -  943   -
              * Disables the Nuspec Analyzer.
    -  944   -
              */
    -  945   -
             public static final String DISABLE_NUSPEC = "disableNuspec";
    -  946   -
             /**
    -  947   -
              * Disables the Central Analyzer.
    -  948   -
              */
    -  949   -
             public static final String DISABLE_CENTRAL = "disableCentral";
    -  950   -
             /**
    -  951   -
              * Disables the Nexus Analyzer.
    -  952   -
              */
    -  953   -
             public static final String DISABLE_NEXUS = "disableNexus";
    -  954   -
             /**
    -  955   -
              * The URL of the nexus server.
    -  956   -
              */
    -  957   -
             public static final String NEXUS_URL = "nexus";
    -  958   -
             /**
    -  959   -
              * Whether or not the defined proxy should be used when connecting to Nexus.
    -  960   -
              */
    -  961   -
             public static final String NEXUS_USES_PROXY = "nexusUsesProxy";
    -  962   -
             /**
    -  963   -
              * The CLI argument name for setting the connection string.
    -  964   -
              */
    -  965   -
             public static final String CONNECTION_STRING = "connectionString";
    -  966   -
             /**
    -  967   -
              * The CLI argument name for setting the database user name.
    -  968   -
              */
    -  969   -
             public static final String DB_NAME = "dbUser";
    -  970   -
             /**
    -  971   -
              * The CLI argument name for setting the database password.
    -  972   -
              */
    -  973   -
             public static final String DB_PASSWORD = "dbPassword";
    -  974   -
             /**
    -  975   -
              * The CLI argument name for setting the database driver name.
    -  976   -
              */
    -  977   -
             public static final String DB_DRIVER = "dbDriverName";
    -  978   -
             /**
    -  979   -
              * The CLI argument name for setting the path to the database driver; in case it is not on the class path.
    -  980   -
              */
    -  981   -
             public static final String DB_DRIVER_PATH = "dbDriverPath";
    -  982   -
             /**
    -  983   -
              * The CLI argument name for setting the path to mono for .NET Assembly analysis on non-windows systems.
    -  984   -
              */
    -  985   -
             public static final String PATH_TO_MONO = "mono";
    -  986   -
             /**
    -  987   -
              * The CLI argument name for setting extra extensions.
    -  988   -
              */
    -  989   -
             public static final String ADDITIONAL_ZIP_EXTENSIONS = "zipExtensions";
    -  990   -
             /**
    -  991   -
              * Exclude path argument.
    -  992   -
              */
    -  993   -
             public static final String EXCLUDE = "exclude";
    -  994  
         }
    +  811   +
     
    +  812   +
         /**
    +  813   +
          * Returns the path to the verbose log file.
    +  814   +
          *
    +  815   +
          * @return the path to the verbose log file
    +  816   +
          */
    +  817   +
         public String getVerboseLog() {
    +  818  0
             return line.getOptionValue(ARGUMENT.VERBOSE_LOG);
    +  819   +
         }
    +  820   +
     
    +  821   +
         /**
    +  822   +
          * Returns the path to the suppression file.
    +  823   +
          *
    +  824   +
          * @return the path to the suppression file
    +  825   +
          */
    +  826   +
         public String getSuppressionFile() {
    +  827  0
             return line.getOptionValue(ARGUMENT.SUPPRESSION_FILE);
    +  828   +
         }
    +  829   +
     
    +  830   +
         /**
    +  831   +
          * <p>
    +  832   +
          * Prints the manifest information to standard output.</p>
    +  833   +
          * <ul><li>Implementation-Title: ${pom.name}</li>
    +  834   +
          * <li>Implementation-Version: ${pom.version}</li></ul>
    +  835   +
          */
    +  836   +
         public void printVersionInfo() {
    +  837  8
             final String version = String.format("%s version %s",
    +  838   +
                     Settings.getString(Settings.KEYS.APPLICATION_VAME, "dependency-check"),
    +  839   +
                     Settings.getString(Settings.KEYS.APPLICATION_VERSION, "Unknown"));
    +  840  8
             System.out.println(version);
    +  841  8
         }
    +  842   +
     
    +  843   +
         /**
    +  844   +
          * Checks if the auto update feature has been disabled. If it has been disabled via the command line this will return false.
    +  845   +
          *
    +  846   +
          * @return <code>true</code> if auto-update is allowed; otherwise <code>false</code>
    +  847   +
          */
    +  848   +
         public boolean isAutoUpdate() {
    +  849  0
             return (line == null) || !line.hasOption(ARGUMENT.DISABLE_AUTO_UPDATE);
    +  850   +
         }
    +  851   +
     
    +  852   +
         /**
    +  853   +
          * Checks if the update only flag has been set.
    +  854   +
          *
    +  855   +
          * @return <code>true</code> if the update only flag has been set; otherwise <code>false</code>.
    +  856   +
          */
    +  857   +
         public boolean isUpdateOnly() {
    +  858  0
             return (line == null) || line.hasOption(ARGUMENT.UPDATE_ONLY);
    +  859   +
         }
    +  860   +
     
    +  861   +
         /**
    +  862   +
          * Returns the database driver name if specified; otherwise null is returned.
    +  863   +
          *
    +  864   +
          * @return the database driver name if specified; otherwise null is returned
    +  865   +
          */
    +  866   +
         public String getDatabaseDriverName() {
    +  867  0
             return line.getOptionValue(ARGUMENT.DB_DRIVER);
    +  868   +
         }
    +  869   +
     
    +  870   +
         /**
    +  871   +
          * Returns the database driver path if specified; otherwise null is returned.
    +  872   +
          *
    +  873   +
          * @return the database driver name if specified; otherwise null is returned
    +  874   +
          */
    +  875   +
         public String getDatabaseDriverPath() {
    +  876  0
             return line.getOptionValue(ARGUMENT.DB_DRIVER_PATH);
    +  877   +
         }
    +  878   +
     
    +  879   +
         /**
    +  880   +
          * Returns the database connection string if specified; otherwise null is returned.
    +  881   +
          *
    +  882   +
          * @return the database connection string if specified; otherwise null is returned
    +  883   +
          */
    +  884   +
         public String getConnectionString() {
    +  885  0
             return line.getOptionValue(ARGUMENT.CONNECTION_STRING);
    +  886   +
         }
    +  887   +
     
    +  888   +
         /**
    +  889   +
          * Returns the database database user name if specified; otherwise null is returned.
    +  890   +
          *
    +  891   +
          * @return the database database user name if specified; otherwise null is returned
    +  892   +
          */
    +  893   +
         public String getDatabaseUser() {
    +  894  0
             return line.getOptionValue(ARGUMENT.DB_NAME);
    +  895   +
         }
    +  896   +
     
    +  897   +
         /**
    +  898   +
          * Returns the database database password if specified; otherwise null is returned.
    +  899   +
          *
    +  900   +
          * @return the database database password if specified; otherwise null is returned
    +  901   +
          */
    +  902   +
         public String getDatabasePassword() {
    +  903  0
             return line.getOptionValue(ARGUMENT.DB_PASSWORD);
    +  904   +
         }
    +  905   +
     
    +  906   +
         /**
    +  907   +
          * Returns the additional Extensions if specified; otherwise null is returned.
    +  908   +
          *
    +  909   +
          * @return the additional Extensions; otherwise null is returned
    +  910   +
          */
    +  911   +
         public String getAdditionalZipExtensions() {
    +  912  0
             return line.getOptionValue(ARGUMENT.ADDITIONAL_ZIP_EXTENSIONS);
    +  913   +
         }
    +  914   +
     
    +  915   +
         /**
    +  916   +
          * A collection of static final strings that represent the possible command line arguments.
    +  917   +
          */
    +  918  72
         public static class ARGUMENT {
    +  919   +
     
    +  920   +
             /**
    +  921   +
              * The long CLI argument name specifying the directory/file to scan.
    +  922   +
              */
    +  923   +
             public static final String SCAN = "scan";
    +  924   +
             /**
    +  925   +
              * The short CLI argument name specifying the directory/file to scan.
    +  926   +
              */
    +  927   +
             public static final String SCAN_SHORT = "s";
    +  928   +
             /**
    +  929   +
              * The long CLI argument name specifying that the CPE/CVE/etc. data should not be automatically updated.
    +  930   +
              */
    +  931   +
             public static final String DISABLE_AUTO_UPDATE = "noupdate";
    +  932   +
             /**
    +  933   +
              * The short CLI argument name specifying that the CPE/CVE/etc. data should not be automatically updated.
    +  934   +
              */
    +  935   +
             public static final String DISABLE_AUTO_UPDATE_SHORT = "n";
    +  936   +
             /**
    +  937   +
              * The long CLI argument name specifying that only the update phase should be executed; no scan should be run.
    +  938   +
              */
    +  939   +
             public static final String UPDATE_ONLY = "updateonly";
    +  940   +
             /**
    +  941   +
              * The long CLI argument name specifying the directory to write the reports to.
    +  942   +
              */
    +  943   +
             public static final String OUT = "out";
    +  944   +
             /**
    +  945   +
              * The short CLI argument name specifying the directory to write the reports to.
    +  946   +
              */
    +  947   +
             public static final String OUT_SHORT = "o";
    +  948   +
             /**
    +  949   +
              * The long CLI argument name specifying the output format to write the reports to.
    +  950   +
              */
    +  951   +
             public static final String OUTPUT_FORMAT = "format";
    +  952   +
             /**
    +  953   +
              * The short CLI argument name specifying the output format to write the reports to.
    +  954   +
              */
    +  955   +
             public static final String OUTPUT_FORMAT_SHORT = "f";
    +  956   +
             /**
    +  957   +
              * The long CLI argument name specifying the name of the application to be scanned.
    +  958   +
              */
    +  959   +
             public static final String APP_NAME = "app";
    +  960   +
             /**
    +  961   +
              * The short CLI argument name specifying the name of the application to be scanned.
    +  962   +
              */
    +  963   +
             public static final String APP_NAME_SHORT = "a";
    +  964   +
             /**
    +  965   +
              * The long CLI argument name asking for help.
    +  966   +
              */
    +  967   +
             public static final String HELP = "help";
    +  968   +
             /**
    +  969   +
              * The long CLI argument name asking for advanced help.
    +  970   +
              */
    +  971   +
             public static final String ADVANCED_HELP = "advancedHelp";
    +  972   +
             /**
    +  973   +
              * The short CLI argument name asking for help.
    +  974   +
              */
    +  975   +
             public static final String HELP_SHORT = "h";
    +  976   +
             /**
    +  977   +
              * The long CLI argument name asking for the version.
    +  978   +
              */
    +  979   +
             public static final String VERSION_SHORT = "v";
    +  980   +
             /**
    +  981   +
              * The short CLI argument name asking for the version.
    +  982   +
              */
    +  983   +
             public static final String VERSION = "version";
    +  984   +
             /**
    +  985   +
              * The CLI argument name indicating the proxy port.
    +  986   +
              */
    +  987   +
             public static final String PROXY_PORT = "proxyport";
    +  988   +
             /**
    +  989   +
              * The CLI argument name indicating the proxy server.
    +  990   +
              */
    +  991   +
             public static final String PROXY_SERVER = "proxyserver";
    +  992   +
             /**
    +  993   +
              * The CLI argument name indicating the proxy url.
    +  994   +
              *
     995   +
              * @deprecated use {@link #PROXY_SERVER} instead
    +  996   +
              */
    +  997   +
             @Deprecated
    +  998   +
             public static final String PROXY_URL = "proxyurl";
    +  999   +
             /**
    +  1000   +
              * The CLI argument name indicating the proxy username.
    +  1001   +
              */
    +  1002   +
             public static final String PROXY_USERNAME = "proxyuser";
    +  1003   +
             /**
    +  1004   +
              * The CLI argument name indicating the proxy password.
    +  1005   +
              */
    +  1006   +
             public static final String PROXY_PASSWORD = "proxypass";
    +  1007   +
             /**
    +  1008   +
              * The short CLI argument name indicating the connection timeout.
    +  1009   +
              */
    +  1010   +
             public static final String CONNECTION_TIMEOUT_SHORT = "c";
    +  1011   +
             /**
    +  1012   +
              * The CLI argument name indicating the connection timeout.
    +  1013   +
              */
    +  1014   +
             public static final String CONNECTION_TIMEOUT = "connectiontimeout";
    +  1015   +
             /**
    +  1016   +
              * The short CLI argument name for setting the location of an additional properties file.
    +  1017   +
              */
    +  1018   +
             public static final String PROP_SHORT = "P";
    +  1019   +
             /**
    +  1020   +
              * The CLI argument name for setting the location of an additional properties file.
    +  1021   +
              */
    +  1022   +
             public static final String PROP = "propertyfile";
    +  1023   +
             /**
    +  1024   +
              * The CLI argument name for setting the location of the data directory.
    +  1025   +
              */
    +  1026   +
             public static final String DATA_DIRECTORY = "data";
    +  1027   +
             /**
    +  1028   +
              * The CLI argument name for setting the URL for the CVE Data Files.
    +  1029   +
              */
    +  1030   +
             public static final String CVE_MOD_12 = "cveUrl12Modified";
    +  1031   +
             /**
    +  1032   +
              * The CLI argument name for setting the URL for the CVE Data Files.
    +  1033   +
              */
    +  1034   +
             public static final String CVE_MOD_20 = "cveUrl20Modified";
    +  1035   +
             /**
    +  1036   +
              * The CLI argument name for setting the URL for the CVE Data Files.
    +  1037   +
              */
    +  1038   +
             public static final String CVE_BASE_12 = "cveUrl12Base";
    +  1039   +
             /**
    +  1040   +
              * The CLI argument name for setting the URL for the CVE Data Files.
    +  1041   +
              */
    +  1042   +
             public static final String CVE_BASE_20 = "cveUrl20Base";
    +  1043   +
             /**
    +  1044   +
              * The short CLI argument name for setting the location of the data directory.
    +  1045   +
              */
    +  1046   +
             public static final String DATA_DIRECTORY_SHORT = "d";
    +  1047   +
             /**
    +  1048   +
              * The CLI argument name for setting the location of the data directory.
    +  1049   +
              */
    +  1050   +
             public static final String VERBOSE_LOG = "log";
    +  1051   +
             /**
    +  1052   +
              * The short CLI argument name for setting the location of the data directory.
    +  1053   +
              */
    +  1054   +
             public static final String VERBOSE_LOG_SHORT = "l";
    +  1055   +
     
    +  1056   +
             /**
    +  1057   +
              * The CLI argument name for setting the depth of symbolic links that will be followed.
    +  1058   +
              */
    +  1059   +
             public static final String SYM_LINK_DEPTH = "symLink";
    +  1060   +
             /**
    +  1061   +
              * The CLI argument name for setting the location of the suppression file.
    +  1062   +
              */
    +  1063   +
             public static final String SUPPRESSION_FILE = "suppression";
    +  1064   +
             /**
    +  1065   +
              * Disables the Jar Analyzer.
    +  1066   +
              */
    +  1067   +
             public static final String DISABLE_JAR = "disableJar";
    +  1068   +
             /**
    +  1069   +
              * Disables the Archive Analyzer.
    +  1070   +
              */
    +  1071   +
             public static final String DISABLE_ARCHIVE = "disableArchive";
    +  1072   +
             /**
    +  1073   +
              * Disables the Python Distribution Analyzer.
    +  1074   +
              */
    +  1075   +
             public static final String DISABLE_PY_DIST = "disablePyDist";
    +  1076   +
             /**
    +  1077   +
              * Disables the Python Package Analyzer.
    +  1078   +
              */
    +  1079   +
             public static final String DISABLE_PY_PKG = "disablePyPkg";
    +  1080   +
             /**
    +  1081   +
              * Disables the Autoconf Analyzer.
    +  1082   +
              */
    +  1083   +
             public static final String DISABLE_AUTOCONF = "disableAutoconf";
    +  1084   +
             /**
    +  1085   +
              * Disables the Cmake Analyzer.
    +  1086   +
              */
    +  1087   +
             public static final String DISABLE_CMAKE = "disableCmake";
    +  1088   +
             /**
    +  1089   +
              * Disables the Assembly Analyzer.
    +  1090   +
              */
    +  1091   +
             public static final String DISABLE_ASSEMBLY = "disableAssembly";
    +  1092   +
             /**
    +  1093   +
              * Disables the Nuspec Analyzer.
    +  1094   +
              */
    +  1095   +
             public static final String DISABLE_NUSPEC = "disableNuspec";
    +  1096   +
             /**
    +  1097   +
              * Disables the Central Analyzer.
    +  1098   +
              */
    +  1099   +
             public static final String DISABLE_CENTRAL = "disableCentral";
    +  1100   +
             /**
    +  1101   +
              * Disables the Nexus Analyzer.
    +  1102   +
              */
    +  1103   +
             public static final String DISABLE_NEXUS = "disableNexus";
    +  1104   +
             /**
    +  1105   +
              * Disables the OpenSSL Analyzer.
    +  1106   +
              */
    +  1107   +
             public static final String DISABLE_OPENSSL = "disableOpenSSL";
    +  1108   +
             /**
    +  1109   +
              * The URL of the nexus server.
    +  1110   +
              */
    +  1111   +
             public static final String NEXUS_URL = "nexus";
    +  1112   +
             /**
    +  1113   +
              * Whether or not the defined proxy should be used when connecting to Nexus.
    +  1114   +
              */
    +  1115   +
             public static final String NEXUS_USES_PROXY = "nexusUsesProxy";
    +  1116   +
             /**
    +  1117   +
              * The CLI argument name for setting the connection string.
    +  1118   +
              */
    +  1119   +
             public static final String CONNECTION_STRING = "connectionString";
    +  1120   +
             /**
    +  1121   +
              * The CLI argument name for setting the database user name.
    +  1122   +
              */
    +  1123   +
             public static final String DB_NAME = "dbUser";
    +  1124   +
             /**
    +  1125   +
              * The CLI argument name for setting the database password.
    +  1126   +
              */
    +  1127   +
             public static final String DB_PASSWORD = "dbPassword";
    +  1128   +
             /**
    +  1129   +
              * The CLI argument name for setting the database driver name.
    +  1130   +
              */
    +  1131   +
             public static final String DB_DRIVER = "dbDriverName";
    +  1132   +
             /**
    +  1133   +
              * The CLI argument name for setting the path to the database driver; in case it is not on the class path.
    +  1134   +
              */
    +  1135   +
             public static final String DB_DRIVER_PATH = "dbDriverPath";
    +  1136   +
             /**
    +  1137   +
              * The CLI argument name for setting the path to mono for .NET Assembly analysis on non-windows systems.
    +  1138   +
              */
    +  1139   +
             public static final String PATH_TO_MONO = "mono";
    +  1140   +
             /**
    +  1141   +
              * The CLI argument name for setting extra extensions.
    +  1142   +
              */
    +  1143   +
             public static final String ADDITIONAL_ZIP_EXTENSIONS = "zipExtensions";
    +  1144   +
             /**
    +  1145   +
              * Exclude path argument.
    +  1146   +
              */
    +  1147   +
             public static final String EXCLUDE = "exclude";
    +  1148   +
         }
    +  1149  
     }
    - + diff --git a/dependency-check-cli/cobertura/org.owasp.dependencycheck.InvalidScanPathException.html b/dependency-check-cli/cobertura/org.owasp.dependencycheck.InvalidScanPathException.html index e052fc65a..01095cc33 100644 --- a/dependency-check-cli/cobertura/org.owasp.dependencycheck.InvalidScanPathException.html +++ b/dependency-check-cli/cobertura/org.owasp.dependencycheck.InvalidScanPathException.html @@ -133,6 +133,6 @@
     }
    - + diff --git a/dependency-check-cli/cpd.html b/dependency-check-cli/cpd.html new file mode 100644 index 000000000..f36bc5bde --- /dev/null +++ b/dependency-check-cli/cpd.html @@ -0,0 +1,268 @@ + + + + + + + + + dependency-check-cli - CPD Results + + + + + + + + + + + + + + + + + + + + + Fork me on GitHub + + + + + +
    + + + + + +
    +
    + +
    + + +
    + +
    +

    CPD Results

    +

    The following document contains the results of PMD's CPD 5.0.2.

    +
    +

    Duplications

    +

    CPD found no problems in your source code.

    +
    +
    +
    + +
    + +
    +
    +
    +

    Copyright © 2012–2015 + OWASP. + All rights reserved. + +

    +
    + + + +
    +
    + + diff --git a/dependency-check-cli/dependency-updates-report.html b/dependency-check-cli/dependency-updates-report.html index 34019d619..37b672753 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 @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -105,7 +105,7 @@ Project Information - +
  • @@ -176,9 +176,16 @@
  • - + - PMD + CPD Report +
  • + +
  • + + + + PMD Report
  • @@ -238,7 +245,7 @@ # of dependencies using the latest version available -4 +22 # of dependencies where the next version available is smaller than an incremental version update @@ -246,11 +253,11 @@ # of dependencies where the next version available is an incremental version update -1 +5 # of dependencies where the next version available is a minor version update -1 +6 # of dependencies where the next version available is a major version update @@ -272,6 +279,102 @@ Next Major +ch.qos.logback +logback-classic +1.1.3 + + +jar + + + + + + +ch.qos.logback +logback-core +1.1.3 + + +jar + + + + + + +com.google.code.findbugs +annotations +3.0.0 + + +jar + + + + + + +com.h2database +h2 +1.3.176 + + +jar + + +1.4.177 + + + +com.sun.mail +mailapi +1.5.2 + + +jar + +1.5.3 + + + + +commons-cli +commons-cli +1.2 + + +jar + + +1.3 + + + +commons-io +commons-io +2.4 + + +jar + + + + + + +commons-lang +commons-lang +2.6 + + +jar + + + + + + junit junit 4.12 @@ -283,6 +386,186 @@ + +org.apache.ant +ant +1.9.5 + + +jar + +1.9.6 + + + + +org.apache.ant +ant-testutil +1.9.5 + + +jar + +1.9.6 + + + + +org.apache.commons +commons-compress +1.9 + + +jar + + + + + + +org.apache.lucene +lucene-analyzers-common +4.7.2 + + +jar + + +4.8.0 +5.0.0 + + +org.apache.lucene +lucene-core +4.7.2 + + +jar + + +4.8.0 +5.0.0 + + +org.apache.lucene +lucene-queryparser +4.7.2 + + +jar + + +4.8.0 +5.0.0 + + +org.apache.lucene +lucene-test-framework +4.7.2 + + +jar + + +4.8.0 +5.0.0 + + +org.apache.maven +maven-core +3.3.3 + + +jar + + + + + + +org.apache.maven +maven-plugin-api +3.3.3 + + +jar + + + + + + +org.apache.maven +maven-settings +3.3.3 + + +jar + + + + + + +org.apache.maven.plugin-testing +maven-plugin-testing-harness +3.3.0 + + +jar + + + + + + +org.apache.maven.plugin-tools +maven-plugin-annotations +3.4 + + +jar + + + + + + +org.apache.maven.plugins +maven-site-plugin +3.4 + + +jar + + + + + + +org.apache.maven.reporting +maven-reporting-api +3.0 + + +jar + + + + + + +org.apache.velocity +velocity +1.7 + + +jar + + + + + org.hamcrest hamcrest-core @@ -294,7 +577,7 @@ - + org.jmockit jmockit @@ -306,6 +589,66 @@ 1.17-beta1 1.17 + + +org.jsoup +jsoup +1.7.2 + + +jar + +1.7.3 +1.8.1 + + + +org.slf4j +slf4j-api +1.7.12 + + +jar + + + + + + +org.slf4j +slf4j-ext +1.7.12 + + +jar + + + + + + +org.slf4j +slf4j-jdk14 +1.7.12 + + +jar + + + + + + +org.slf4j +slf4j-simple +1.7.12 + + +jar + + + + Status Group Id @@ -334,22 +677,22 @@ Next Minor Next Major - -commons-cli -commons-cli -1.2 + +org.owasp +dependency-check-core +1.3.0 compile jar -1.3 + org.owasp -dependency-check-core -1.2.11 +dependency-check-utils +1.3.0 compile jar @@ -358,18 +701,6 @@ - -org.owasp -dependency-check-utils -1.2.11 -compile - -jar - - - - - Status Group Id Artifact Id @@ -385,32 +716,206 @@

    Dependency Updates

    -

    commons-cli:commons-cli

    +

    ch.qos.logback:logback-classic

    - + - - + + - - + + - - - - + - - + + - + + + + + +
    Status There is at least one newer minor version available. Minor updates are sometimes passive.
     No newer versions available.
    Group Idcommons-cli
    ch.qos.logback
    Artifact Idcommons-cli
    Current Version1.2
    logback-classic
    Scopecompile
    Current Version1.1.3
    ClassifierScope
    Classifier
    Typejar
    +
    +

    ch.qos.logback:logback-core

    + + + + + + + + + + + + + + + + + + + + + +
    Status No newer versions available.
    Group Idch.qos.logback
    Artifact Idlogback-core
    Current Version1.1.3
    Scope
    Classifier
    Typejar
    +
    +

    com.google.code.findbugs:annotations

    + + + + + + + + + + + + + + + + + + + + + +
    Status No newer versions available.
    Group Idcom.google.code.findbugs
    Artifact Idannotations
    Current Version3.0.0
    Scope
    Classifier
    Typejar
    +
    +

    com.h2database:h2

    + + + + + + + + + + + + + + + + + + + + - + -
    Status There is at least one newer minor version available. Minor updates are sometimes passive.
    Group Idcom.h2database
    Artifact Idh2
    Current Version1.3.176
    Scope
    Classifier
    Type jar
    Newer versions1.3 Next 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 Latest Minor +
    +

    com.sun.mail:mailapi

    + + + + + + + + + + + + + + + + + + + + + + + + +
    Status There is at least one newer incremental version available. Incremental updates are typically passive.
    Group Idcom.sun.mail
    Artifact Idmailapi
    Current Version1.5.2
    Scope
    Classifier
    Typejar
    Newer versions1.5.3 Next Incremental
    1.5.4 Latest Incremental
    +
    +

    commons-cli:commons-cli

    + + + + + + + + + + + + + + + + + + + + + + + + +
    Status There is at least one newer minor version available. Minor updates are sometimes passive.
    Group Idcommons-cli
    Artifact Idcommons-cli
    Current Version1.2
    Scope
    Classifier
    Typejar
    Newer versions1.3 Next Minor
    1.3.1 Latest Minor
    +
    +

    commons-io:commons-io

    + + + + + + + + + + + + + + + + + + + + + +
    Status No newer versions available.
    Group Idcommons-io
    Artifact Idcommons-io
    Current Version2.4
    Scope
    Classifier
    Typejar
    +
    +

    commons-lang:commons-lang

    + + + + + + + + + + + + + + + + + + + + + +
    Status No newer versions available.
    Group Idcommons-lang
    Artifact Idcommons-lang
    Current Version2.6
    Scope
    Classifier
    Typejar

    junit:junit

    @@ -436,6 +941,384 @@
    Type jar
    +

    org.apache.ant:ant

    + + + + + + + + + + + + + + + + + + + + + + + + +
    Status There is at least one newer incremental version available. Incremental updates are typically passive.
    Group Idorg.apache.ant
    Artifact Idant
    Current Version1.9.5
    Scope
    Classifier
    Typejar
    Newer versions1.9.6 Next Incremental
    +
    +

    org.apache.ant:ant-testutil

    + + + + + + + + + + + + + + + + + + + + + + + + +
    Status There is at least one newer incremental version available. Incremental updates are typically passive.
    Group Idorg.apache.ant
    Artifact Idant-testutil
    Current Version1.9.5
    Scope
    Classifier
    Typejar
    Newer versions1.9.6 Next Incremental
    +
    +

    org.apache.commons:commons-compress

    + + + + + + + + + + + + + + + + + + + + + +
    Status No newer versions available.
    Group Idorg.apache.commons
    Artifact Idcommons-compress
    Current Version1.9
    Scope
    Classifier
    Typejar
    +
    +

    org.apache.lucene:lucene-analyzers-common

    + + + + + + + + + + + + + + + + + + + + + + + + +
    Status There is at least one newer minor version available. Minor updates are sometimes passive.
    Group Idorg.apache.lucene
    Artifact Idlucene-analyzers-common
    Current Version4.7.2
    Scope
    Classifier
    Typejar
    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 Latest Major
    +
    +

    org.apache.lucene:lucene-core

    + + + + + + + + + + + + + + + + + + + + + + + + +
    Status There is at least one newer minor version available. Minor updates are sometimes passive.
    Group Idorg.apache.lucene
    Artifact Idlucene-core
    Current Version4.7.2
    Scope
    Classifier
    Typejar
    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 Latest Major
    +
    +

    org.apache.lucene:lucene-queryparser

    + + + + + + + + + + + + + + + + + + + + + + + + +
    Status There is at least one newer minor version available. Minor updates are sometimes passive.
    Group Idorg.apache.lucene
    Artifact Idlucene-queryparser
    Current Version4.7.2
    Scope
    Classifier
    Typejar
    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 Latest Major
    +
    +

    org.apache.lucene:lucene-test-framework

    + + + + + + + + + + + + + + + + + + + + + + + + +
    Status There is at least one newer minor version available. Minor updates are sometimes passive.
    Group Idorg.apache.lucene
    Artifact Idlucene-test-framework
    Current Version4.7.2
    Scope
    Classifier
    Typejar
    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 Latest Major
    +
    +

    org.apache.maven:maven-core

    + + + + + + + + + + + + + + + + + + + + + +
    Status No newer versions available.
    Group Idorg.apache.maven
    Artifact Idmaven-core
    Current Version3.3.3
    Scope
    Classifier
    Typejar
    +
    +

    org.apache.maven:maven-plugin-api

    + + + + + + + + + + + + + + + + + + + + + +
    Status No newer versions available.
    Group Idorg.apache.maven
    Artifact Idmaven-plugin-api
    Current Version3.3.3
    Scope
    Classifier
    Typejar
    +
    +

    org.apache.maven:maven-settings

    + + + + + + + + + + + + + + + + + + + + + +
    Status No newer versions available.
    Group Idorg.apache.maven
    Artifact Idmaven-settings
    Current Version3.3.3
    Scope
    Classifier
    Typejar
    +
    +

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

    + + + + + + + + + + + + + + + + + + + + + +
    Status No newer versions available.
    Group Idorg.apache.maven.plugin-testing
    Artifact Idmaven-plugin-testing-harness
    Current Version3.3.0
    Scope
    Classifier
    Typejar
    +
    +

    org.apache.maven.plugin-tools:maven-plugin-annotations

    + + + + + + + + + + + + + + + + + + + + + +
    Status No newer versions available.
    Group Idorg.apache.maven.plugin-tools
    Artifact Idmaven-plugin-annotations
    Current Version3.4
    Scope
    Classifier
    Typejar
    +
    +

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

    + + + + + + + + + + + + + + + + + + + + + +
    Status No newer versions available.
    Group Idorg.apache.maven.plugins
    Artifact Idmaven-site-plugin
    Current Version3.4
    Scope
    Classifier
    Typejar
    +
    +

    org.apache.maven.reporting:maven-reporting-api

    + + + + + + + + + + + + + + + + + + + + + +
    Status No newer versions available.
    Group Idorg.apache.maven.reporting
    Artifact Idmaven-reporting-api
    Current Version3.0
    Scope
    Classifier
    Typejar
    +
    +

    org.apache.velocity:velocity

    + + + + + + + + + + + + + + + + + + + + + +
    Status No newer versions available.
    Group Idorg.apache.velocity
    Artifact Idvelocity
    Current Version1.7
    Scope
    Classifier
    Typejar
    +

    org.hamcrest:hamcrest-core

    @@ -487,6 +1370,33 @@
    Newer versions 1.17-beta1 Next Incremental
    1.17-beta2 Latest Incremental
    1.17 Next Minor
    +

    org.jsoup:jsoup

    + + + + + + + + + + + + + + + + + + + + + + + + +
    Status There is at least one newer incremental version available. Incremental updates are typically passive.
    Group Idorg.jsoup
    Artifact Idjsoup
    Current Version1.7.2
    Scope
    Classifier
    Typejar
    Newer versions1.7.3 Next Incremental
    1.8.1 Next Minor
    1.8.2 Latest Minor
    +

    org.owasp:dependency-check-core

    @@ -500,7 +1410,7 @@ - + @@ -524,7 +1434,7 @@ - + @@ -533,6 +1443,102 @@ +
    dependency-check-core
    Current Version1.2.11
    1.3.0
    Scope compile
    dependency-check-utils
    Current Version1.2.11
    1.3.0
    Scope compile
    Typejar
    +
    +

    org.slf4j:slf4j-api

    + + + + + + + + + + + + + + + + + + + + + +
    Status No newer versions available.
    Group Idorg.slf4j
    Artifact Idslf4j-api
    Current Version1.7.12
    Scope
    Classifier
    Typejar
    +
    +

    org.slf4j:slf4j-ext

    + + + + + + + + + + + + + + + + + + + + + +
    Status No newer versions available.
    Group Idorg.slf4j
    Artifact Idslf4j-ext
    Current Version1.7.12
    Scope
    Classifier
    Typejar
    +
    +

    org.slf4j:slf4j-jdk14

    + + + + + + + + + + + + + + + + + + + + + +
    Status No newer versions available.
    Group Idorg.slf4j
    Artifact Idslf4j-jdk14
    Current Version1.7.12
    Scope
    Classifier
    Typejar
    +
    +

    org.slf4j:slf4j-simple

    + + + + + + + + + + + + + + + + + + + + +
    Status No newer versions available.
    Group Idorg.slf4j
    Artifact Idslf4j-simple
    Current Version1.7.12
    Scope
    Classifier
    Type jar
    diff --git a/dependency-check-cli/findbugs.html b/dependency-check-cli/findbugs.html index 77503be86..7f6913b82 100644 --- a/dependency-check-cli/findbugs.html +++ b/dependency-check-cli/findbugs.html @@ -1,13 +1,13 @@ - + dependency-check-cli - FindBugs Bug Detector Report @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -105,7 +105,7 @@ Project Information - +
  • @@ -178,9 +178,16 @@
  • - + - PMD + CPD Report +
  • + +
  • + + + + PMD Report
  • @@ -247,7 +254,7 @@ Missing Classes 4 -1 +0 0 0
    @@ -255,25 +262,7 @@ - - - -
    ClassBugs
    org.owasp.dependencycheck.App1
    -
    -

    org.owasp.dependencycheck.App

    - - - - - - - - - - - - -
    BugCategoryDetailsLinePriority
    Hard coded reference to an absolute pathname in org.owasp.dependencycheck.App.runScan(String, String, String, String[], String[])STYLEDMI_HARDCODED_ABSOLUTE_FILENAME154Medium
    +Bugs diff --git a/dependency-check-cli/index.html b/dependency-check-cli/index.html index b3b1a0030..3b2ed2a9f 100644 --- a/dependency-check-cli/index.html +++ b/dependency-check-cli/index.html @@ -1,13 +1,13 @@ - + dependency-check-cli - About @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -103,7 +103,7 @@ Project Information - +
  • @@ -155,7 +155,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/issue-tracking.html b/dependency-check-cli/issue-tracking.html
    index c4d790da0..0e6325db6 100644
    --- a/dependency-check-cli/issue-tracking.html
    +++ b/dependency-check-cli/issue-tracking.html
    @@ -1,13 +1,13 @@
     
     
     
       
         
         
    -    
    +    
         
         dependency-check-cli - Issue Tracking
         
    @@ -54,7 +54,7 @@
                     
                         
                                   
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -147,7 +147,7 @@
  • - +
  • diff --git a/dependency-check-cli/license.html b/dependency-check-cli/license.html index cb545185d..5be0b19ef 100644 --- a/dependency-check-cli/license.html +++ b/dependency-check-cli/license.html @@ -1,13 +1,13 @@ - + dependency-check-cli - Project License @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -147,7 +147,7 @@ - +
  • diff --git a/dependency-check-cli/mail-lists.html b/dependency-check-cli/mail-lists.html index 1374841ac..fac7baf13 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 @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -147,7 +147,7 @@ - +
  • diff --git a/dependency-check-cli/plugin-updates-report.html b/dependency-check-cli/plugin-updates-report.html index 8c5ab0eca..68d538362 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 @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -105,7 +105,7 @@ Project Information - +
  • @@ -176,9 +176,16 @@
  • - + - PMD + CPD Report +
  • + +
  • + + + + PMD Report
  • @@ -238,7 +245,7 @@ # of plugins using the latest version available -12 +15 # of plugins where the next version available is smaller than an incremental version update @@ -250,7 +257,7 @@ # of plugins where the next version available is a minor version update -6 +3 # of plugins where the next version available is a major version update @@ -273,20 +280,20 @@ Next Major Dependency status - + org.apache.maven.plugins maven-antrun-plugin -1.3 +1.8 + -1.4 org.apache.maven.plugins maven-assembly-plugin -2.5.3 +2.5.5 @@ -306,21 +313,21 @@ org.apache.maven.plugins maven-compiler-plugin -3.2 +3.3 - + org.apache.maven.plugins maven-dependency-plugin -2.9 - - 2.10 + + + @@ -353,14 +360,14 @@ - + org.apache.maven.plugins maven-gpg-plugin -1.5 - - 1.6 + + + @@ -376,7 +383,7 @@ org.apache.maven.plugins maven-jar-plugin -2.5 +2.6 @@ -386,17 +393,17 @@ org.apache.maven.plugins maven-plugin-plugin -3.3 +3.2 -3.4 +3.3 org.apache.maven.plugins maven-release-plugin -2.5.1 +2.5.2 @@ -436,7 +443,7 @@ org.codehaus.mojo appassembler-maven-plugin -1.9 +1.10 @@ -446,7 +453,7 @@ org.codehaus.mojo cobertura-maven-plugin -2.6 +2.7 @@ -473,7 +480,7 @@ - + @@ -482,10 +489,7 @@ - - - -
    Status There is at least one newer minor version available. Minor updates are sometimes passive.
     No newer versions available.
    Group Id org.apache.maven.plugins
    maven-antrun-plugin
    Current Version1.3
    Newer versions1.4 Next Minor
    1.5
    1.6
    1.7
    1.8 Latest Minor
    +1.8

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

    @@ -500,7 +504,7 @@ -
    maven-assembly-plugin
    Current Version2.5.3
    +2.5.5

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

    @@ -530,13 +534,13 @@ -
    maven-compiler-plugin
    Current Version3.2
    +3.3

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

    - + @@ -545,10 +549,7 @@ - - - -
    Status There is at least one newer minor version available. Minor updates are sometimes passive.
     No newer versions available.
    Group Id org.apache.maven.plugins
    maven-dependency-plugin
    Current Version2.9
    Newer versions2.10 Next Minor
    +2.10

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

    @@ -602,7 +603,7 @@
    - + @@ -611,10 +612,7 @@ - - - -
    Status There is at least one newer minor version available. Minor updates are sometimes passive.
     No newer versions available.
    Group Id org.apache.maven.plugins
    maven-gpg-plugin
    Current Version1.5
    Newer versions1.6 Next Minor
    +1.6

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

    @@ -644,7 +642,7 @@ -
    maven-jar-plugin
    Current Version2.5
    +2.6

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

    @@ -659,10 +657,10 @@ - + -
    maven-plugin-plugin
    Current Version3.3
    3.2
    Newer versions3.4 Next Minor
    +3.3 Next Minor
    3.4 Latest Minor

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

    @@ -677,7 +675,7 @@ -
    maven-release-plugin
    Current Version2.5.1
    +2.5.2

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

    @@ -740,7 +738,7 @@ -
    appassembler-maven-plugin
    Current Version1.9
    +1.10

    Plugin org.codehaus.mojo:cobertura-maven-plugin

    @@ -755,7 +753,7 @@ -
    cobertura-maven-plugin
    Current Version2.6
    +2.7 diff --git a/dependency-check-cli/pmd.html b/dependency-check-cli/pmd.html index 26997b43f..5a0d66de5 100644 --- a/dependency-check-cli/pmd.html +++ b/dependency-check-cli/pmd.html @@ -1,13 +1,13 @@ - + dependency-check-cli - PMD Results @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -105,7 +105,7 @@ Project Information - +
  • @@ -176,9 +176,16 @@ Checkstyle
  • +
  • + + + + CPD Report +
  • +
  • - PMD + PMD Report
  • @@ -233,10 +240,19 @@

    PMD Results

    -

    The following document contains the results of PMD 5.0.5.

    +

    The following document contains the results of PMD 5.0.2.

    Files

    +

    org/owasp/dependencycheck/App.java

    + + + + + + +
    ViolationLine
    Useless parentheses.148
    +

    org/owasp/dependencycheck/CliParser.java

    @@ -244,43 +260,55 @@ - + - + - + - + - + - + - + - + - + - + - + - + -
    Line
    Useless parentheses.414
    118
    Useless parentheses.423
    453
    Useless parentheses.432
    462
    Useless parentheses.441
    471
    Useless parentheses.450
    498
    Useless parentheses.459
    507
    Useless parentheses.468
    516
    Useless parentheses.477
    525
    Useless parentheses.486
    534
    Useless parentheses.495
    543
    Useless parentheses.504
    552
    Useless parentheses.728
    561
    Useless parentheses.737
    +570 + +Useless parentheses. +579 + +Useless parentheses. +588 + +Useless parentheses. +849 + +Useless parentheses. +858 diff --git a/dependency-check-cli/project-info.html b/dependency-check-cli/project-info.html index 52a249bf6..c4b041484 100644 --- a/dependency-check-cli/project-info.html +++ b/dependency-check-cli/project-info.html @@ -1,13 +1,13 @@ - + dependency-check-cli - Project Information @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -147,7 +147,7 @@ - +
  • diff --git a/dependency-check-cli/project-reports.html b/dependency-check-cli/project-reports.html index 099c6feed..c037f6210 100644 --- a/dependency-check-cli/project-reports.html +++ b/dependency-check-cli/project-reports.html @@ -1,13 +1,13 @@ - + dependency-check-cli - Generated Reports @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -105,7 +105,7 @@ Project Information - +
  • Project Reports @@ -176,9 +176,16 @@
  • - + - PMD + CPD Report +
  • + +
  • + + + + PMD Report
  • @@ -268,9 +275,12 @@ Checkstyle Report on coding style conventions. -PMD -Verification of coding rules. +CPD Report +Duplicate code detection. +PMD Report +Verification of coding rules. + FindBugs Report Generates a source code report with the FindBugs Library. diff --git a/dependency-check-cli/project-summary.html b/dependency-check-cli/project-summary.html index 49a91a63c..90a9aaae7 100644 --- a/dependency-check-cli/project-summary.html +++ b/dependency-check-cli/project-summary.html @@ -1,13 +1,13 @@ - + dependency-check-cli - Project Summary @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -147,7 +147,7 @@ - +
  • @@ -239,7 +239,7 @@ dependency-check-cli Version -1.2.11 +1.3.0 Type jar diff --git a/dependency-check-cli/source-repository.html b/dependency-check-cli/source-repository.html index f9d260c5c..d02333aeb 100644 --- a/dependency-check-cli/source-repository.html +++ b/dependency-check-cli/source-repository.html @@ -1,13 +1,13 @@ - + dependency-check-cli - Source Repository @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -147,7 +147,7 @@ - +
  • diff --git a/dependency-check-cli/surefire-report.html b/dependency-check-cli/surefire-report.html index 59facdaef..c8bcaf972 100644 --- a/dependency-check-cli/surefire-report.html +++ b/dependency-check-cli/surefire-report.html @@ -1,13 +1,13 @@ - + dependency-check-cli - Surefire Report @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -105,7 +105,7 @@ Project Information - +
  • @@ -176,9 +176,16 @@
  • - + - PMD + CPD Report +
  • + +
  • + + + + PMD Report
  • @@ -262,12 +269,12 @@ function toggleDisplay(elementId) { Success Rate Time -9 +11 0 0 0 100% -0.036
    +0.522

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


    Package List

    @@ -283,12 +290,12 @@ function toggleDisplay(elementId) { Time org.owasp.dependencycheck -9 +11 0 0 0 100% -0.036
    +0.522

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

    org.owasp.dependencycheck

    @@ -303,6 +310,15 @@ function toggleDisplay(elementId) { Success Rate Time + +AppTest +2 +0 +0 +0 +100% +0.491 + CliParserTest 9 @@ -310,21 +326,32 @@ function toggleDisplay(elementId) { 0 0 100% -0.036

    +0.031

    Test Cases

    [Summary] [Package List] [Test Cases]

    +

    AppTest

    + + + + + + + + +
    testEnsureCanonicalPath20.49
    testEnsureCanonicalPath0.001
    +

    CliParserTest

    - + - + @@ -332,7 +359,7 @@ function toggleDisplay(elementId) { - + @@ -340,7 +367,7 @@ function toggleDisplay(elementId) { - + @@ -348,7 +375,7 @@ function toggleDisplay(elementId) { - + diff --git a/dependency-check-cli/taglist.html b/dependency-check-cli/taglist.html index f3aaed0a8..23041b7dc 100644 --- a/dependency-check-cli/taglist.html +++ b/dependency-check-cli/taglist.html @@ -1,13 +1,13 @@ - + dependency-check-cli - Tag List report @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -105,7 +105,7 @@ Project Information - +
  • @@ -176,9 +176,16 @@
  • - + - PMD + CPD Report +
  • + +
  • + + + + PMD Report
  • diff --git a/dependency-check-cli/team-list.html b/dependency-check-cli/team-list.html index e88680f23..b8eb29632 100644 --- a/dependency-check-cli/team-list.html +++ b/dependency-check-cli/team-list.html @@ -1,13 +1,13 @@ - + dependency-check-cli - Team list @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -147,7 +147,7 @@ - +
  • @@ -231,6 +231,13 @@
  • + + + + + + +
    testParse_printHelp0.032
    0.027
    testParse_printVersionInfo0
    0.001
    testParse_help
    testParse_scan0.001
    0
    testParse
    testParse_unknown0
    0.001
    testParse_version
    testParse_scan_unknownFile0.001
    0
    testParse_scan_withFileExists Will.Stranathan@owasp.org OWASP https://www.owasp.org/developer
    Dale Visserdvisser@ida.orgInstitute for Defense Analyseshttps://www.ida.org/ developer

    Contributors

    diff --git a/dependency-check-cli/xref-test/allclasses-frame.html b/dependency-check-cli/xref-test/allclasses-frame.html index 0bba97722..09eb198b1 100644 --- a/dependency-check-cli/xref-test/allclasses-frame.html +++ b/dependency-check-cli/xref-test/allclasses-frame.html @@ -12,6 +12,9 @@ diff --git a/dependency-check-cli/xref-test/index.html b/dependency-check-cli/xref-test/index.html index 36e584e73..56eaf87a9 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.2.11 Reference + Dependency-Check Command Line 1.3.0 Reference diff --git a/dependency-check-cli/xref-test/org/owasp/dependencycheck/AppTest.html b/dependency-check-cli/xref-test/org/owasp/dependencycheck/AppTest.html new file mode 100644 index 000000000..8cdc2a417 --- /dev/null +++ b/dependency-check-cli/xref-test/org/owasp/dependencycheck/AppTest.html @@ -0,0 +1,86 @@ + + + +AppTest xref + + + +
    +1   /*
    +2    * Copyright 2015 OWASP.
    +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  package org.owasp.dependencycheck;
    +17  
    +18  import org.junit.After;
    +19  import org.junit.AfterClass;
    +20  import org.junit.Before;
    +21  import org.junit.BeforeClass;
    +22  import org.junit.Test;
    +23  import static org.junit.Assert.*;
    +24  
    +25  /**
    +26   *
    +27   * @author jeremy
    +28   */
    +29  public class AppTest {
    +30  
    +31      public AppTest() {
    +32      }
    +33  
    +34      @BeforeClass
    +35      public static void setUpClass() {
    +36      }
    +37  
    +38      @AfterClass
    +39      public static void tearDownClass() {
    +40      }
    +41  
    +42      @Before
    +43      public void setUp() {
    +44      }
    +45  
    +46      @After
    +47      public void tearDown() {
    +48      }
    +49  
    +50      /**
    +51       * Test of ensureCanonicalPath method, of class App.
    +52       */
    +53      @Test
    +54      public void testEnsureCanonicalPath() {
    +55          String file = "../*.jar";
    +56          App instance = new App();
    +57          String result = instance.ensureCanonicalPath(file);
    +58          assertFalse(result.contains(".."));
    +59          assertTrue(result.endsWith("*.jar"));
    +60      }
    +61  
    +62      /**
    +63       * Test of ensureCanonicalPath method, of class App.
    +64       */
    +65      @Test
    +66      public void testEnsureCanonicalPath2() {
    +67          String file = "../some/skip/../path/file.txt";
    +68          App instance = new App();
    +69          String expResult = "/some/path/file.txt";
    +70          String result = instance.ensureCanonicalPath(file);
    +71          assertTrue("result=" + result, result.endsWith(expResult));
    +72      }
    +73  }
    +
    +
    + + + 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 b0a111132..345d098d7 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.2.11 Reference Package org.owasp.dependencycheck + Dependency-Check Command Line 1.3.0 Reference Package org.owasp.dependencycheck @@ -16,6 +16,9 @@ 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 37ae6ab7f..4739ef5a5 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.2.11 Reference Package org.owasp.dependencycheck + Dependency-Check Command Line 1.3.0 Reference Package org.owasp.dependencycheck @@ -36,6 +36,11 @@ + + AppTest + + + CliParserTest diff --git a/dependency-check-cli/xref-test/overview-frame.html b/dependency-check-cli/xref-test/overview-frame.html index a6fc86ed1..fb39eca17 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.2.11 Reference + Dependency-Check Command Line 1.3.0 Reference diff --git a/dependency-check-cli/xref-test/overview-summary.html b/dependency-check-cli/xref-test/overview-summary.html index fece9d527..0c575d8cf 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.2.11 Reference + Dependency-Check Command Line 1.3.0 Reference @@ -24,7 +24,7 @@
    -

    Dependency-Check Command Line 1.2.11 Reference

    +

    Dependency-Check Command Line 1.3.0 Reference

    diff --git a/dependency-check-cli/xref/index.html b/dependency-check-cli/xref/index.html index 36e584e73..56eaf87a9 100644 --- a/dependency-check-cli/xref/index.html +++ b/dependency-check-cli/xref/index.html @@ -4,7 +4,7 @@ - Dependency-Check Command Line 1.2.11 Reference + Dependency-Check Command Line 1.3.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 70146f81d..91299d2d8 100644 --- a/dependency-check-cli/xref/org/owasp/dependencycheck/App.html +++ b/dependency-check-cli/xref/org/owasp/dependencycheck/App.html @@ -25,342 +25,438 @@ 17 */18package org.owasp.dependencycheck; 19 -20import java.io.File; -21import java.io.FileNotFoundException; -22import java.io.IOException; -23import java.io.InputStream; -24import java.util.ArrayList; -25import java.util.Arrays; +20import ch.qos.logback.classic.LoggerContext; +21import ch.qos.logback.classic.encoder.PatternLayoutEncoder; +22import java.io.File; +23import java.io.FileNotFoundException; +24import java.io.IOException; +25import java.util.ArrayList; 26import java.util.HashSet; 27import java.util.List; 28import java.util.Set; -29import java.util.logging.Level; -30import java.util.logging.Logger; -31import org.apache.commons.cli.ParseException; -32import org.owasp.dependencycheck.data.nvdcve.CveDB; -33import org.owasp.dependencycheck.data.nvdcve.DatabaseException; -34import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties; -35import org.owasp.dependencycheck.dependency.Dependency; -36import org.owasp.dependencycheck.org.apache.tools.ant.DirectoryScanner; -37import org.owasp.dependencycheck.reporting.ReportGenerator; -38import org.owasp.dependencycheck.utils.LogUtils; -39import org.owasp.dependencycheck.utils.Settings; -40 -41/** -42 * The command line interface for the DependencyCheck application. -43 * -44 * @author Jeremy Long -45 */ -46publicclassApp { -47 -48/** -49 * The location of the log properties configuration file. -50 */ -51privatestaticfinal String LOG_PROPERTIES_FILE = "log.properties"; -52 -53/** -54 * The logger. -55 */ -56privatestaticfinal Logger LOGGER = Logger.getLogger(App.class.getName()); -57 -58/** -59 * The main method for the application. -60 * -61 * @param args the command line arguments -62 */ -63publicstaticvoid main(String[] args) { -64try { -65 Settings.initialize(); -66finalApp app = newApp(); -67 app.run(args); -68 } finally { -69 Settings.cleanup(true); -70 } -71 } -72 -73/** -74 * Main CLI entry-point into the application. -75 * -76 * @param args the command line arguments -77 */ -78publicvoid run(String[] args) { -79finalCliParser cli = newCliParser(); -80 -81try { -82 cli.parse(args); -83 } catch (FileNotFoundException ex) { +29import org.apache.commons.cli.ParseException; +30import org.owasp.dependencycheck.data.nvdcve.CveDB; +31import org.owasp.dependencycheck.data.nvdcve.DatabaseException; +32import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties; +33import org.owasp.dependencycheck.dependency.Dependency; +34import org.owasp.dependencycheck.org.apache.tools.ant.DirectoryScanner; +35import org.owasp.dependencycheck.reporting.ReportGenerator; +36import org.owasp.dependencycheck.utils.Settings; +37import org.slf4j.Logger; +38import org.slf4j.LoggerFactory; +39import ch.qos.logback.core.FileAppender; +40import org.slf4j.impl.StaticLoggerBinder; +41 +42/** +43 * The command line interface for the DependencyCheck application. +44 * +45 * @author Jeremy Long +46 */ +47publicclassApp { +48 +49/** +50 * The logger. +51 */ +52privatestaticfinal Logger LOGGER = LoggerFactory.getLogger(App.class); +53 +54/** +55 * The main method for the application. +56 * +57 * @param args the command line arguments +58 */ +59publicstaticvoid main(String[] args) { +60try { +61 Settings.initialize(); +62finalApp app = newApp(); +63 app.run(args); +64 } finally { +65 Settings.cleanup(true); +66 } +67 } +68 +69/** +70 * Main CLI entry-point into the application. +71 * +72 * @param args the command line arguments +73 */ +74publicvoid run(String[] args) { +75finalCliParser cli = newCliParser(); +76 +77try { +78 cli.parse(args); +79 } catch (FileNotFoundException ex) { +80 System.err.println(ex.getMessage()); +81 cli.printHelp(); +82return; +83 } catch (ParseException ex) { 84 System.err.println(ex.getMessage()); 85 cli.printHelp(); 86return; -87 } catch (ParseException ex) { -88 System.err.println(ex.getMessage()); -89 cli.printHelp(); -90return; +87 } +88 +89if (cli.getVerboseLog() != null) { +90 prepareLogger(cli.getVerboseLog()); 91 } 92 -93final InputStream in = App.class.getClassLoader().getResourceAsStream(LOG_PROPERTIES_FILE); -94 LogUtils.prepareLogger(in, cli.getVerboseLog()); -95 -96if (cli.isGetVersion()) { -97 cli.printVersionInfo(); -98 } elseif (cli.isUpdateOnly()) { +93if (cli.isGetVersion()) { +94 cli.printVersionInfo(); +95 } elseif (cli.isUpdateOnly()) { +96 populateSettings(cli); +97 runUpdateOnly(); +98 } elseif (cli.isRunScan()) { 99 populateSettings(cli); -100 runUpdateOnly(); -101 } elseif (cli.isRunScan()) { -102 populateSettings(cli); -103try { -104 runScan(cli.getReportDirectory(), cli.getReportFormat(), cli.getApplicationName(), cli.getScanFiles(), cli.getExcludeList()); -105 } catch (InvalidScanPathException ex) { -106 LOGGER.log(Level.SEVERE, "An invalid scan path was detected; unable to scan '//*' paths"); -107 } -108 } else { -109 cli.printHelp(); -110 } -111 } -112 -113/** -114 * Scans the specified directories and writes the dependency reports to the reportDirectory. -115 * -116 * @param reportDirectory the path to the directory where the reports will be written -117 * @param outputFormat the output format of the report -118 * @param applicationName the application name for the report -119 * @param files the files/directories to scan -120 * @param excludes the patterns for files/directories to exclude -121 * -122 * @throws InvalidScanPathException thrown if the path to scan starts with "//" -123 */ -124privatevoid runScan(String reportDirectory, String outputFormat, String applicationName, String[] files, -125 String[] excludes) throws InvalidScanPathException { -126 Engine engine = null; -127try { -128 engine = new Engine(); -129 List<String> antStylePaths = new ArrayList<String>(); -130if (excludes == null || excludes.length == 0) { -131for (String file : files) { -132if (file.contains("*") || file.contains("?")) { -133 antStylePaths.add(file); -134 } else { -135 engine.scan(file); -136 } -137 } -138 } else { -139 antStylePaths = Arrays.asList(files); -140 } -141 -142final Set<File> paths = new HashSet<File>(); -143for (String file : antStylePaths) { -144final DirectoryScanner scanner = new DirectoryScanner(); -145 String include = file.replace('\\', '/'); -146 File baseDir; -147 -148if (include.startsWith("//")) { -149thrownewInvalidScanPathException("Unable to scan paths specified by //"); -150 } elseif (include.startsWith("./")) { -151 baseDir = new File("."); -152 include = include.substring(2); -153 } elseif (include.startsWith("/")) { -154 baseDir = new File("/"); -155 include = include.substring(1); -156 } elseif (include.contains("/")) { -157finalint pos = include.indexOf('/'); -158final String tmp = include.substring(0, pos); -159if (tmp.contains("*") || tmp.contains("?")) { -160 baseDir = new File("."); -161 } else { -162 baseDir = new File(tmp); -163 include = include.substring(pos + 1); -164 } -165 } else { //no path info - must just be a file in the working directory -166 baseDir = new File("."); -167 } -168 scanner.setBasedir(baseDir); -169 scanner.setIncludes(include); -170if (excludes != null && excludes.length > 0) { -171 scanner.addExcludes(excludes); -172 } -173 scanner.scan(); -174if (scanner.getIncludedFilesCount() > 0) { -175for (String s : scanner.getIncludedFiles()) { -176final File f = new File(baseDir, s); -177 paths.add(f); -178 } -179 } -180 } -181 engine.scan(paths); -182 -183 engine.analyzeDependencies(); -184final List<Dependency> dependencies = engine.getDependencies(); -185 DatabaseProperties prop = null; -186 CveDB cve = null; -187try { -188 cve = new CveDB(); -189 cve.open(); -190 prop = cve.getDatabaseProperties(); -191 } catch (DatabaseException ex) { -192 LOGGER.log(Level.FINE, "Unable to retrieve DB Properties", ex); -193 } finally { -194if (cve != null) { -195 cve.close(); -196 } -197 } -198final ReportGenerator report = new ReportGenerator(applicationName, dependencies, engine.getAnalyzers(), prop); -199try { -200 report.generateReports(reportDirectory, outputFormat); -201 } catch (IOException ex) { -202 LOGGER.log(Level.SEVERE, "There was an IO error while attempting to generate the report."); -203 LOGGER.log(Level.FINE, null, ex); -204 } catch (Throwable ex) { -205 LOGGER.log(Level.SEVERE, "There was an error while attempting to generate the report."); -206 LOGGER.log(Level.FINE, null, ex); -207 } -208 } catch (DatabaseException ex) { -209 LOGGER.log(Level.SEVERE, "Unable to connect to the dependency-check database; analysis has stopped"); -210 LOGGER.log(Level.FINE, "", ex); -211 } finally { -212if (engine != null) { -213 engine.cleanup(); -214 } -215 } -216 } -217 -218/** -219 * Only executes the update phase of dependency-check. -220 */ -221privatevoid runUpdateOnly() { -222 Engine engine = null; -223try { -224 engine = new Engine(); -225 engine.doUpdates(); -226 } catch (DatabaseException ex) { -227 LOGGER.log(Level.SEVERE, "Unable to connect to the dependency-check database; analysis has stopped"); -228 LOGGER.log(Level.FINE, "", ex); -229 } finally { -230if (engine != null) { -231 engine.cleanup(); -232 } -233 } -234 } -235 -236/** -237 * Updates the global Settings. -238 * -239 * @param cli a reference to the CLI Parser that contains the command line arguments used to set the corresponding settings in -240 * the core engine. -241 */ -242privatevoid populateSettings(CliParser cli) { -243 -244finalboolean autoUpdate = cli.isAutoUpdate(); -245final String connectionTimeout = cli.getConnectionTimeout(); -246final String proxyServer = cli.getProxyServer(); -247final String proxyPort = cli.getProxyPort(); -248final String proxyUser = cli.getProxyUsername(); -249final String proxyPass = cli.getProxyPassword(); -250final String dataDirectory = cli.getDataDirectory(); -251final File propertiesFile = cli.getPropertiesFile(); -252final String suppressionFile = cli.getSuppressionFile(); -253finalboolean jarDisabled = cli.isJarDisabled(); -254finalboolean archiveDisabled = cli.isArchiveDisabled(); -255finalboolean pyDistDisabled = cli.isPythonDistributionDisabled(); -256finalboolean pyPkgDisabled = cli.isPythonPackageDisabled(); -257finalboolean assemblyDisabled = cli.isAssemblyDisabled(); -258finalboolean nuspecDisabled = cli.isNuspecDisabled(); -259finalboolean centralDisabled = cli.isCentralDisabled(); -260finalboolean nexusDisabled = cli.isNexusDisabled(); -261final String nexusUrl = cli.getNexusUrl(); -262final String databaseDriverName = cli.getDatabaseDriverName(); -263final String databaseDriverPath = cli.getDatabaseDriverPath(); -264final String connectionString = cli.getConnectionString(); -265final String databaseUser = cli.getDatabaseUser(); -266final String databasePassword = cli.getDatabasePassword(); -267final String additionalZipExtensions = cli.getAdditionalZipExtensions(); -268final String pathToMono = cli.getPathToMono(); -269 -270if (propertiesFile != null) { -271try { -272 Settings.mergeProperties(propertiesFile); -273 } catch (FileNotFoundException ex) { -274final String msg = String.format("Unable to load properties file '%s'", propertiesFile.getPath()); -275 LOGGER.log(Level.SEVERE, msg); -276 LOGGER.log(Level.FINE, null, ex); +100try { +101 runScan(cli.getReportDirectory(), cli.getReportFormat(), cli.getApplicationName(), cli.getScanFiles(), +102 cli.getExcludeList(), cli.getSymLinkDepth()); +103 } catch (InvalidScanPathException ex) { +104 LOGGER.error("An invalid scan path was detected; unable to scan '//*' paths"); +105 } +106 } else { +107 cli.printHelp(); +108 } +109 } +110 +111/** +112 * Scans the specified directories and writes the dependency reports to the reportDirectory. +113 * +114 * @param reportDirectory the path to the directory where the reports will be written +115 * @param outputFormat the output format of the report +116 * @param applicationName the application name for the report +117 * @param files the files/directories to scan +118 * @param excludes the patterns for files/directories to exclude +119 * @param symLinkDepth the depth that symbolic links will be followed +120 * +121 * @throws InvalidScanPathException thrown if the path to scan starts with "//" +122 */ +123privatevoid runScan(String reportDirectory, String outputFormat, String applicationName, String[] files, +124 String[] excludes, int symLinkDepth) throws InvalidScanPathException { +125 Engine engine = null; +126try { +127 engine = new Engine(); +128final List<String> antStylePaths = new ArrayList<String>(); +129for (String file : files) { +130final String antPath = ensureCanonicalPath(file); +131 antStylePaths.add(antPath); +132 } +133 +134final Set<File> paths = new HashSet<File>(); +135for (String file : antStylePaths) { +136 LOGGER.debug("Scanning {}", file); +137final DirectoryScanner scanner = new DirectoryScanner(); +138 String include = file.replace('\\', '/'); +139 File baseDir; +140 +141if (include.startsWith("//")) { +142thrownewInvalidScanPathException("Unable to scan paths specified by //"); +143 } else { +144finalint pos = getLastFileSeparator(include); +145final String tmpBase = include.substring(0, pos); +146final String tmpInclude = include.substring(pos + 1); +147if (tmpInclude.indexOf('*') >= 0 || tmpInclude.indexOf('?') >= 0 +148 || (new File(include)).isFile()) { +149 baseDir = new File(tmpBase); +150 include = tmpInclude; +151 } else { +152 baseDir = new File(tmpBase, tmpInclude); +153 include = "**/*"; +154 } +155 } +156//LOGGER.debug("baseDir: {}", baseDir); +157//LOGGER.debug("include: {}", include); +158 scanner.setBasedir(baseDir); +159 scanner.setIncludes(include); +160 scanner.setMaxLevelsOfSymlinks(symLinkDepth); +161if (symLinkDepth <= 0) { +162 scanner.setFollowSymlinks(false); +163 } +164if (excludes != null && excludes.length > 0) { +165 scanner.addExcludes(excludes); +166 } +167 scanner.scan(); +168if (scanner.getIncludedFilesCount() > 0) { +169for (String s : scanner.getIncludedFiles()) { +170final File f = new File(baseDir, s); +171 LOGGER.debug("Found file {}", f.toString()); +172 paths.add(f); +173 } +174 } +175 } +176 engine.scan(paths); +177 +178 engine.analyzeDependencies(); +179final List<Dependency> dependencies = engine.getDependencies(); +180 DatabaseProperties prop = null; +181 CveDB cve = null; +182try { +183 cve = new CveDB(); +184 cve.open(); +185 prop = cve.getDatabaseProperties(); +186 } catch (DatabaseException ex) { +187 LOGGER.debug("Unable to retrieve DB Properties", ex); +188 } finally { +189if (cve != null) { +190 cve.close(); +191 } +192 } +193final ReportGenerator report = new ReportGenerator(applicationName, dependencies, engine.getAnalyzers(), prop); +194try { +195 report.generateReports(reportDirectory, outputFormat); +196 } catch (IOException ex) { +197 LOGGER.error("There was an IO error while attempting to generate the report."); +198 LOGGER.debug("", ex); +199 } catch (Throwable ex) { +200 LOGGER.error("There was an error while attempting to generate the report."); +201 LOGGER.debug("", ex); +202 } +203 } catch (DatabaseException ex) { +204 LOGGER.error("Unable to connect to the dependency-check database; analysis has stopped"); +205 LOGGER.debug("", ex); +206 } finally { +207if (engine != null) { +208 engine.cleanup(); +209 } +210 } +211 } +212 +213/** +214 * Only executes the update phase of dependency-check. +215 */ +216privatevoid runUpdateOnly() { +217 Engine engine = null; +218try { +219 engine = new Engine(); +220 engine.doUpdates(); +221 } catch (DatabaseException ex) { +222 LOGGER.error("Unable to connect to the dependency-check database; analysis has stopped"); +223 LOGGER.debug("", ex); +224 } finally { +225if (engine != null) { +226 engine.cleanup(); +227 } +228 } +229 } +230 +231/** +232 * Updates the global Settings. +233 * +234 * @param cli a reference to the CLI Parser that contains the command line arguments used to set the corresponding settings in +235 * the core engine. +236 */ +237privatevoid populateSettings(CliParser cli) { +238 +239finalboolean autoUpdate = cli.isAutoUpdate(); +240final String connectionTimeout = cli.getConnectionTimeout(); +241final String proxyServer = cli.getProxyServer(); +242final String proxyPort = cli.getProxyPort(); +243final String proxyUser = cli.getProxyUsername(); +244final String proxyPass = cli.getProxyPassword(); +245final String dataDirectory = cli.getDataDirectory(); +246final File propertiesFile = cli.getPropertiesFile(); +247final String suppressionFile = cli.getSuppressionFile(); +248finalboolean jarDisabled = cli.isJarDisabled(); +249finalboolean archiveDisabled = cli.isArchiveDisabled(); +250finalboolean pyDistDisabled = cli.isPythonDistributionDisabled(); +251finalboolean cMakeDisabled = cli.isCmakeDisabled(); +252finalboolean pyPkgDisabled = cli.isPythonPackageDisabled(); +253finalboolean autoconfDisabled = cli.isAutoconfDisabled(); +254finalboolean assemblyDisabled = cli.isAssemblyDisabled(); +255finalboolean nuspecDisabled = cli.isNuspecDisabled(); +256finalboolean centralDisabled = cli.isCentralDisabled(); +257finalboolean nexusDisabled = cli.isNexusDisabled(); +258final String nexusUrl = cli.getNexusUrl(); +259final String databaseDriverName = cli.getDatabaseDriverName(); +260final String databaseDriverPath = cli.getDatabaseDriverPath(); +261final String connectionString = cli.getConnectionString(); +262final String databaseUser = cli.getDatabaseUser(); +263final String databasePassword = cli.getDatabasePassword(); +264final String additionalZipExtensions = cli.getAdditionalZipExtensions(); +265final String pathToMono = cli.getPathToMono(); +266final String cveMod12 = cli.getModifiedCve12Url(); +267final String cveMod20 = cli.getModifiedCve20Url(); +268final String cveBase12 = cli.getBaseCve12Url(); +269final String cveBase20 = cli.getBaseCve20Url(); +270 +271if (propertiesFile != null) { +272try { +273 Settings.mergeProperties(propertiesFile); +274 } catch (FileNotFoundException ex) { +275 LOGGER.error("Unable to load properties file '{}'", propertiesFile.getPath()); +276 LOGGER.debug("", ex); 277 } catch (IOException ex) { -278final String msg = String.format("Unable to find properties file '%s'", propertiesFile.getPath()); -279 LOGGER.log(Level.SEVERE, msg); -280 LOGGER.log(Level.FINE, null, ex); -281 } -282 } -283// We have to wait until we've merged the properties before attempting to set whether we use -284// the proxy for Nexus since it could be disabled in the properties, but not explicitly stated -285// on the command line -286finalboolean nexusUsesProxy = cli.isNexusUsesProxy(); -287if (dataDirectory != null) { -288 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory); -289 } elseif (System.getProperty("basedir") != null) { -290final File dataDir = new File(System.getProperty("basedir"), "data"); -291 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath()); -292 } else { -293final File jarPath = new File(App.class.getProtectionDomain().getCodeSource().getLocation().getPath()); -294final File base = jarPath.getParentFile(); -295final String sub = Settings.getString(Settings.KEYS.DATA_DIRECTORY); -296final File dataDir = new File(base, sub); -297 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath()); -298 } -299 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate); -300if (proxyServer != null && !proxyServer.isEmpty()) { -301 Settings.setString(Settings.KEYS.PROXY_SERVER, proxyServer); -302 } -303if (proxyPort != null && !proxyPort.isEmpty()) { -304 Settings.setString(Settings.KEYS.PROXY_PORT, proxyPort); -305 } -306if (proxyUser != null && !proxyUser.isEmpty()) { -307 Settings.setString(Settings.KEYS.PROXY_USERNAME, proxyUser); -308 } -309if (proxyPass != null && !proxyPass.isEmpty()) { -310 Settings.setString(Settings.KEYS.PROXY_PASSWORD, proxyPass); -311 } -312if (connectionTimeout != null && !connectionTimeout.isEmpty()) { -313 Settings.setString(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout); -314 } -315if (suppressionFile != null && !suppressionFile.isEmpty()) { -316 Settings.setString(Settings.KEYS.SUPPRESSION_FILE, suppressionFile); -317 } -318 -319//File Type Analyzer Settings -320 Settings.setBoolean(Settings.KEYS.ANALYZER_JAR_ENABLED, !jarDisabled); -321 Settings.setBoolean(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, !archiveDisabled); -322 Settings.setBoolean(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, !pyDistDisabled); -323 Settings.setBoolean(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, !pyPkgDisabled); -324 Settings.setBoolean(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, !nuspecDisabled); -325 Settings.setBoolean(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, !assemblyDisabled); -326 -327 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, !centralDisabled); -328 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, !nexusDisabled); -329if (nexusUrl != null && !nexusUrl.isEmpty()) { -330 Settings.setString(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl); -331 } -332 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_PROXY, nexusUsesProxy); -333if (databaseDriverName != null && !databaseDriverName.isEmpty()) { -334 Settings.setString(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName); -335 } -336if (databaseDriverPath != null && !databaseDriverPath.isEmpty()) { -337 Settings.setString(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath); -338 } -339if (connectionString != null && !connectionString.isEmpty()) { -340 Settings.setString(Settings.KEYS.DB_CONNECTION_STRING, connectionString); -341 } -342if (databaseUser != null && !databaseUser.isEmpty()) { -343 Settings.setString(Settings.KEYS.DB_USER, databaseUser); -344 } -345if (databasePassword != null && !databasePassword.isEmpty()) { -346 Settings.setString(Settings.KEYS.DB_PASSWORD, databasePassword); -347 } -348if (additionalZipExtensions != null && !additionalZipExtensions.isEmpty()) { -349 Settings.setString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, additionalZipExtensions); -350 } -351if (pathToMono != null && !pathToMono.isEmpty()) { -352 Settings.setString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono); -353 } -354 } -355 } +278 LOGGER.error("Unable to find properties file '{}'", propertiesFile.getPath()); +279 LOGGER.debug("", ex); +280 } +281 } +282// We have to wait until we've merged the properties before attempting to set whether we use +283// the proxy for Nexus since it could be disabled in the properties, but not explicitly stated +284// on the command line +285finalboolean nexusUsesProxy = cli.isNexusUsesProxy(); +286if (dataDirectory != null) { +287 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory); +288 } elseif (System.getProperty("basedir") != null) { +289final File dataDir = new File(System.getProperty("basedir"), "data"); +290 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath()); +291 } else { +292final File jarPath = new File(App.class.getProtectionDomain().getCodeSource().getLocation().getPath()); +293final File base = jarPath.getParentFile(); +294final String sub = Settings.getString(Settings.KEYS.DATA_DIRECTORY); +295final File dataDir = new File(base, sub); +296 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath()); +297 } +298 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate); +299if (proxyServer != null && !proxyServer.isEmpty()) { +300 Settings.setString(Settings.KEYS.PROXY_SERVER, proxyServer); +301 } +302if (proxyPort != null && !proxyPort.isEmpty()) { +303 Settings.setString(Settings.KEYS.PROXY_PORT, proxyPort); +304 } +305if (proxyUser != null && !proxyUser.isEmpty()) { +306 Settings.setString(Settings.KEYS.PROXY_USERNAME, proxyUser); +307 } +308if (proxyPass != null && !proxyPass.isEmpty()) { +309 Settings.setString(Settings.KEYS.PROXY_PASSWORD, proxyPass); +310 } +311if (connectionTimeout != null && !connectionTimeout.isEmpty()) { +312 Settings.setString(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout); +313 } +314if (suppressionFile != null && !suppressionFile.isEmpty()) { +315 Settings.setString(Settings.KEYS.SUPPRESSION_FILE, suppressionFile); +316 } +317 +318//File Type Analyzer Settings +319 Settings.setBoolean(Settings.KEYS.ANALYZER_JAR_ENABLED, !jarDisabled); +320 Settings.setBoolean(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, !archiveDisabled); +321 Settings.setBoolean(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, !pyDistDisabled); +322 Settings.setBoolean(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, !pyPkgDisabled); +323 Settings.setBoolean(Settings.KEYS.ANALYZER_AUTOCONF_ENABLED, !autoconfDisabled); +324 Settings.setBoolean(Settings.KEYS.ANALYZER_CMAKE_ENABLED, !cMakeDisabled); +325 Settings.setBoolean(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, !nuspecDisabled); +326 Settings.setBoolean(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, !assemblyDisabled); +327 Settings.setBoolean(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, !cli.isOpenSSLDisabled()); +328 +329 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, !centralDisabled); +330 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, !nexusDisabled); +331if (nexusUrl != null && !nexusUrl.isEmpty()) { +332 Settings.setString(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl); +333 } +334 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_PROXY, nexusUsesProxy); +335if (databaseDriverName != null && !databaseDriverName.isEmpty()) { +336 Settings.setString(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName); +337 } +338if (databaseDriverPath != null && !databaseDriverPath.isEmpty()) { +339 Settings.setString(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath); +340 } +341if (connectionString != null && !connectionString.isEmpty()) { +342 Settings.setString(Settings.KEYS.DB_CONNECTION_STRING, connectionString); +343 } +344if (databaseUser != null && !databaseUser.isEmpty()) { +345 Settings.setString(Settings.KEYS.DB_USER, databaseUser); +346 } +347if (databasePassword != null && !databasePassword.isEmpty()) { +348 Settings.setString(Settings.KEYS.DB_PASSWORD, databasePassword); +349 } +350if (additionalZipExtensions != null && !additionalZipExtensions.isEmpty()) { +351 Settings.setString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, additionalZipExtensions); +352 } +353if (pathToMono != null && !pathToMono.isEmpty()) { +354 Settings.setString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono); +355 } +356if (cveBase12 != null && !cveBase12.isEmpty()) { +357 Settings.setString(Settings.KEYS.CVE_SCHEMA_1_2, cveBase12); +358 Settings.setString(Settings.KEYS.CVE_SCHEMA_2_0, cveBase20); +359 Settings.setString(Settings.KEYS.CVE_MODIFIED_12_URL, cveMod12); +360 Settings.setString(Settings.KEYS.CVE_MODIFIED_20_URL, cveMod20); +361 } +362 } +363 +364/** +365 * Creates a file appender and adds it to logback. +366 * +367 * @param verboseLog the path to the verbose log file +368 */ +369privatevoid prepareLogger(String verboseLog) { +370final StaticLoggerBinder loggerBinder = StaticLoggerBinder.getSingleton(); +371final LoggerContext context = (LoggerContext) loggerBinder.getLoggerFactory(); +372 +373final PatternLayoutEncoder encoder = new PatternLayoutEncoder(); +374 encoder.setPattern("%d %C:%L%n%-5level - %msg%n"); +375 encoder.setContext(context); +376 encoder.start(); +377final FileAppender fa = new FileAppender(); +378 fa.setAppend(true); +379 fa.setEncoder(encoder); +380 fa.setContext(context); +381 fa.setFile(verboseLog); +382final File f = new File(verboseLog); +383 String name = f.getName(); +384finalint i = name.lastIndexOf('.'); +385if (i > 1) { +386 name = name.substring(0, i); +387 } +388 fa.setName(name); +389 fa.start(); +390final ch.qos.logback.classic.Logger rootLogger = context.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME); +391 rootLogger.addAppender(fa); +392 } +393 +394/** +395 * Takes a path and resolves it to be a canonical & absolute path. The caveats are that this method will take an Ant style +396 * file selector path (../someDir/**\/*.jar) and convert it to an absolute/canonical path (at least to the left of the first * +397 * or ?). +398 * +399 * @param path the path to canonicalize +400 * @return the canonical path +401 */ +402protected String ensureCanonicalPath(String path) { +403 String basePath = null; +404 String wildCards = null; +405final String file = path.replace('\\', '/'); +406if (file.contains("*") || file.contains("?")) { +407 +408int pos = getLastFileSeparator(file); +409if (pos < 0) { +410return file; +411 } +412 pos += 1; +413 basePath = file.substring(0, pos); +414 wildCards = file.substring(pos); +415 } else { +416 basePath = file; +417 } +418 +419 File f = new File(basePath); +420try { +421 f = f.getCanonicalFile(); +422if (wildCards != null) { +423 f = new File(f, wildCards); +424 } +425 } catch (IOException ex) { +426 LOGGER.warn("Invalid path '{}' was provided.", path); +427 LOGGER.debug("Invalid path provided", ex); +428 } +429return f.getAbsolutePath().replace('\\', '/'); +430 } +431 +432/** +433 * Returns the position of the last file separator. +434 * +435 * @param file a file path +436 * @return the position of the last file separator +437 */ +438privateint getLastFileSeparator(String file) { +439if (file.contains("*") || file.contains("?")) { +440int p1 = file.indexOf('*'); +441int p2 = file.indexOf('?'); +442 p1 = p1 > 0 ? p1 : file.length(); +443 p2 = p2 > 0 ? p2 : file.length(); +444int pos = p1 < p2 ? p1 : p2; +445 pos = file.lastIndexOf('/', pos); +446return pos; +447 } else { +448return file.lastIndexOf('/'); +449 } +450 } +451 }
    diff --git a/dependency-check-cli/xref/org/owasp/dependencycheck/CliParser.html b/dependency-check-cli/xref/org/owasp/dependencycheck/CliParser.html index 847a09074..4c6363dc6 100644 --- a/dependency-check-cli/xref/org/owasp/dependencycheck/CliParser.html +++ b/dependency-check-cli/xref/org/owasp/dependencycheck/CliParser.html @@ -27,980 +27,1134 @@ 1920import java.io.File; 21import java.io.FileNotFoundException; -22import java.util.logging.Logger; -23 -24import org.apache.commons.cli.CommandLine; -25import org.apache.commons.cli.CommandLineParser; -26import org.apache.commons.cli.HelpFormatter; -27import org.apache.commons.cli.Option; -28import org.apache.commons.cli.OptionBuilder; -29import org.apache.commons.cli.OptionGroup; -30import org.apache.commons.cli.Options; -31import org.apache.commons.cli.ParseException; -32import org.apache.commons.cli.PosixParser; -33import org.owasp.dependencycheck.reporting.ReportGenerator.Format; -34import org.owasp.dependencycheck.utils.InvalidSettingException; -35import org.owasp.dependencycheck.utils.Settings; -36 -37/** -38 * A utility to parse command line arguments for the DependencyCheck. -39 * -40 * @author Jeremy Long -41 */ -42publicfinalclassCliParser { -43 -44/** -45 * The logger. -46 */ -47privatestaticfinal Logger LOGGER = Logger.getLogger(CliParser.class.getName()); -48/** -49 * The command line. -50 */ -51private CommandLine line; -52/** -53 * Indicates whether the arguments are valid. -54 */ -55privateboolean isValid = true; -56 -57/** -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 PosixParser(); -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 (isRunScan()) { -94 validatePathExists(getScanFiles(), ARGUMENT.SCAN); -95 validatePathExists(getReportDirectory(), ARGUMENT.OUT); -96if (getPathToMono() != null) { -97 validatePathExists(getPathToMono(), ARGUMENT.PATH_TO_MONO); -98 } -99if (!line.hasOption(ARGUMENT.APP_NAME)) { -100thrownew ParseException("Missing 'app' argument; the scan cannot be run without the an application name."); -101 } -102if (line.hasOption(ARGUMENT.OUTPUT_FORMAT)) { -103final String format = line.getOptionValue(ARGUMENT.OUTPUT_FORMAT); -104try { -105 Format.valueOf(format); -106 } catch (IllegalArgumentException ex) { -107final String msg = String.format("An invalid 'format' of '%s' was specified. " -108 + "Supported output formats are XML, HTML, VULN, or ALL", format); -109thrownew ParseException(msg); -110 } -111 } -112 } -113 } -114 -115/** -116 * 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 -117 * FileNotFoundException is thrown. -118 * -119 * @param paths the paths to validate if they exists -120 * @param optType the option being validated (e.g. scan, out, etc.) -121 * @throws FileNotFoundException is thrown if one of the paths being validated does not exist. -122 */ -123privatevoid validatePathExists(String[] paths, String optType) throws FileNotFoundException { -124for (String path : paths) { -125 validatePathExists(path, optType); -126 } -127 } -128 -129/** -130 * Validates whether or not the path points at a file that exists; if the path does not point to an existing file a -131 * FileNotFoundException is thrown. -132 * -133 * @param path the paths to validate if they exists -134 * @param argumentName the argument being validated (e.g. scan, out, etc.) -135 * @throws FileNotFoundException is thrown if the path being validated does not exist. -136 */ -137privatevoid validatePathExists(String path, String argumentName) throws FileNotFoundException { -138if (path == null) { -139 isValid = false; -140final String msg = String.format("Invalid '%s' argument: null", argumentName); -141thrownew FileNotFoundException(msg); -142 } elseif (!path.contains("*") && !path.contains("?")) { -143 File f = new File(path); -144if ("o".equalsIgnoreCase(argumentName.substring(0, 1)) && !"ALL".equalsIgnoreCase(this.getReportFormat())) { -145final String checkPath = path.toLowerCase(); -146if (checkPath.endsWith(".html") || checkPath.endsWith(".xml") || checkPath.endsWith(".htm")) { -147if (f.getParentFile() == null) { -148 f = new File(".", path); -149 } -150if (!f.getParentFile().isDirectory()) { -151 isValid = false; -152final String msg = String.format("Invalid '%s' argument: '%s'", argumentName, path); -153thrownew FileNotFoundException(msg); -154 } -155 } -156 } else { -157if (!f.exists()) { -158 isValid = false; -159final String msg = String.format("Invalid '%s' argument: '%s'", argumentName, path); -160thrownew FileNotFoundException(msg); -161 } -162 } -163 } elseif (path.startsWith("//") || path.startsWith("\\\\")) { -164 isValid = false; -165final String msg = String.format("Invalid '%s' argument: '%s'%nUnable to scan paths that start with '//'.", argumentName, path); -166thrownew FileNotFoundException(msg); -167 } -168 } -169 -170/** -171 * Generates an Options collection that is used to parse the command line and to display the help message. -172 * -173 * @return the command line options used for parsing the command line -174 */ -175 @SuppressWarnings("static-access") -176private Options createCommandLineOptions() { -177final Options options = new Options(); -178 addStandardOptions(options); -179 addAdvancedOptions(options); -180 addDeprecatedOptions(options); -181return options; -182 } -183 -184/** -185 * Adds the standard command line options to the given options collection. -186 * -187 * @param options a collection of command line arguments -188 * @throws IllegalArgumentException thrown if there is an exception -189 */ -190 @SuppressWarnings("static-access") -191privatevoid addStandardOptions(final Options options) throws IllegalArgumentException { -192final Option help = new Option(ARGUMENT.HELP_SHORT, ARGUMENT.HELP, false, -193"Print this message."); -194 -195final Option advancedHelp = OptionBuilder.withLongOpt(ARGUMENT.ADVANCED_HELP) -196 .withDescription("Print the advanced help message.").create(); -197 -198final Option version = new Option(ARGUMENT.VERSION_SHORT, ARGUMENT.VERSION, -199 false, "Print the version information."); -200 -201final Option noUpdate = new Option(ARGUMENT.DISABLE_AUTO_UPDATE_SHORT, ARGUMENT.DISABLE_AUTO_UPDATE, -202 false, "Disables the automatic updating of the CPE data."); -203 -204final Option appName = OptionBuilder.withArgName("name").hasArg().withLongOpt(ARGUMENT.APP_NAME) -205 .withDescription("The name of the application being scanned. This is a required argument.") -206 .create(ARGUMENT.APP_NAME_SHORT); -207 -208final Option path = OptionBuilder.withArgName("path").hasArg().withLongOpt(ARGUMENT.SCAN) -209 .withDescription("The path to scan - this option can be specified multiple times. Ant style" -210 + " paths are supported (e.g. path/**/*.jar).") -211 .create(ARGUMENT.SCAN_SHORT); -212 -213final Option excludes = OptionBuilder.withArgName("pattern").hasArg().withLongOpt(ARGUMENT.EXCLUDE) -214 .withDescription("Specify and exclusion pattern. This option can be specified multiple times" -215 + " and it accepts Ant style excludsions.") -216 .create(); -217 -218final Option props = OptionBuilder.withArgName("file").hasArg().withLongOpt(ARGUMENT.PROP) -219 .withDescription("A property file to load.") -220 .create(ARGUMENT.PROP_SHORT); -221 -222final Option out = OptionBuilder.withArgName("path").hasArg().withLongOpt(ARGUMENT.OUT) -223 .withDescription("The folder to write reports to. This defaults to the current directory. " -224 + "It is possible to set this to a specific file name if the format argument is not set to ALL.") -225 .create(ARGUMENT.OUT_SHORT); -226 -227final Option outputFormat = OptionBuilder.withArgName("format").hasArg().withLongOpt(ARGUMENT.OUTPUT_FORMAT) -228 .withDescription("The output format to write to (XML, HTML, VULN, ALL). The default is HTML.") -229 .create(ARGUMENT.OUTPUT_FORMAT_SHORT); -230 -231final Option verboseLog = OptionBuilder.withArgName("file").hasArg().withLongOpt(ARGUMENT.VERBOSE_LOG) -232 .withDescription("The file path to write verbose logging information.") -233 .create(ARGUMENT.VERBOSE_LOG_SHORT); -234 -235final Option suppressionFile = OptionBuilder.withArgName("file").hasArg().withLongOpt(ARGUMENT.SUPPRESSION_FILE) -236 .withDescription("The file path to the suppression XML file.") -237 .create(); -238 -239//This is an option group because it can be specified more then once. -240final OptionGroup og = new OptionGroup(); -241 og.addOption(path); +22 +23import org.apache.commons.cli.CommandLine; +24import org.apache.commons.cli.CommandLineParser; +25import org.apache.commons.cli.HelpFormatter; +26import org.apache.commons.cli.Option; +27import org.apache.commons.cli.OptionBuilder; +28import org.apache.commons.cli.OptionGroup; +29import org.apache.commons.cli.Options; +30import org.apache.commons.cli.ParseException; +31import org.apache.commons.cli.PosixParser; +32import org.owasp.dependencycheck.reporting.ReportGenerator.Format; +33import org.owasp.dependencycheck.utils.InvalidSettingException; +34import org.owasp.dependencycheck.utils.Settings; +35import org.slf4j.Logger; +36import org.slf4j.LoggerFactory; +37 +38/** +39 * A utility to parse command line arguments for the DependencyCheck. +40 * +41 * @author Jeremy Long +42 */ +43publicfinalclassCliParser { +44 +45/** +46 * The logger. +47 */ +48privatestaticfinal Logger LOGGER = LoggerFactory.getLogger(CliParser.class); +49/** +50 * The command line. +51 */ +52private CommandLine line; +53/** +54 * Indicates whether the arguments are valid. +55 */ +56privateboolean isValid = true; +57 +58/** +59 * Parses the arguments passed in and captures the results for later use. +60 * +61 * @param args the command line arguments +62 * @throws FileNotFoundException is thrown when a 'file' argument does not 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 PosixParser(); +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 SCAN or CPE command line arguments that does not +90 * exist. +91 * @throws ParseException is thrown if there is an exception parsing the command line. +92 */ +93privatevoid validateArgs() throws FileNotFoundException, ParseException { +94if (isRunScan()) { +95 validatePathExists(getScanFiles(), ARGUMENT.SCAN); +96 validatePathExists(getReportDirectory(), ARGUMENT.OUT); +97if (getPathToMono() != null) { +98 validatePathExists(getPathToMono(), ARGUMENT.PATH_TO_MONO); +99 } +100if (!line.hasOption(ARGUMENT.APP_NAME)) { +101thrownew ParseException("Missing 'app' argument; the scan cannot be run without the an application name."); +102 } +103if (line.hasOption(ARGUMENT.OUTPUT_FORMAT)) { +104final String format = line.getOptionValue(ARGUMENT.OUTPUT_FORMAT); +105try { +106 Format.valueOf(format); +107 } catch (IllegalArgumentException ex) { +108final String msg = String.format("An invalid 'format' of '%s' was specified. " +109 + "Supported output formats are XML, HTML, VULN, or ALL", format); +110thrownew ParseException(msg); +111 } +112 } +113if ((getBaseCve12Url() != null || getBaseCve20Url() != null || getModifiedCve12Url() != null || getModifiedCve20Url() != null) +114 && (getBaseCve12Url() == null || getBaseCve20Url() == null || getModifiedCve12Url() == null || getModifiedCve20Url() == null)) { +115final String msg = "If one of the CVE URLs is specified they must all be specified; please add the missing CVE URL."; +116thrownew ParseException(msg); +117 } +118if (line.hasOption((ARGUMENT.SYM_LINK_DEPTH))) { +119try { +120finalint i = Integer.parseInt(line.getOptionValue(ARGUMENT.SYM_LINK_DEPTH)); +121if (i < 0) { +122thrownew ParseException("Symbolic Link Depth (symLink) must be greater than zero."); +123 } +124 } catch (NumberFormatException ex) { +125thrownew ParseException("Symbolic Link Depth (symLink) is not a number."); +126 } +127 } +128 } +129 } +130 +131/** +132 * 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 +133 * FileNotFoundException is thrown. +134 * +135 * @param paths the paths to validate if they exists +136 * @param optType the option being validated (e.g. scan, out, etc.) +137 * @throws FileNotFoundException is thrown if one of the paths being validated does not exist. +138 */ +139privatevoid validatePathExists(String[] paths, String optType) throws FileNotFoundException { +140for (String path : paths) { +141 validatePathExists(path, optType); +142 } +143 } +144 +145/** +146 * Validates whether or not the path points at a file that exists; if the path does not point to an existing file a +147 * FileNotFoundException is thrown. +148 * +149 * @param path the paths to validate if they exists +150 * @param argumentName the argument being validated (e.g. scan, out, etc.) +151 * @throws FileNotFoundException is thrown if the path being validated does not exist. +152 */ +153privatevoid validatePathExists(String path, String argumentName) throws FileNotFoundException { +154if (path == null) { +155 isValid = false; +156final String msg = String.format("Invalid '%s' argument: null", argumentName); +157thrownew FileNotFoundException(msg); +158 } elseif (!path.contains("*") && !path.contains("?")) { +159 File f = new File(path); +160if ("o".equalsIgnoreCase(argumentName.substring(0, 1)) && !"ALL".equalsIgnoreCase(this.getReportFormat())) { +161final String checkPath = path.toLowerCase(); +162if (checkPath.endsWith(".html") || checkPath.endsWith(".xml") || checkPath.endsWith(".htm")) { +163if (f.getParentFile() == null) { +164 f = new File(".", path); +165 } +166if (!f.getParentFile().isDirectory()) { +167 isValid = false; +168final String msg = String.format("Invalid '%s' argument: '%s'", argumentName, path); +169thrownew FileNotFoundException(msg); +170 } +171 } +172 } else { +173if (!f.exists()) { +174 isValid = false; +175final String msg = String.format("Invalid '%s' argument: '%s'", argumentName, path); +176thrownew FileNotFoundException(msg); +177 } +178 } +179 } elseif (path.startsWith("//") || path.startsWith("\\\\")) { +180 isValid = false; +181final String msg = String.format("Invalid '%s' argument: '%s'%nUnable to scan paths that start with '//'.", argumentName, path); +182thrownew FileNotFoundException(msg); +183 } +184 } +185 +186/** +187 * Generates an Options collection that is used to parse the command line and to display the help message. +188 * +189 * @return the command line options used for parsing the command line +190 */ +191 @SuppressWarnings("static-access") +192private Options createCommandLineOptions() { +193final Options options = new Options(); +194 addStandardOptions(options); +195 addAdvancedOptions(options); +196 addDeprecatedOptions(options); +197return options; +198 } +199 +200/** +201 * Adds the standard command line options to the given options collection. +202 * +203 * @param options a collection of command line arguments +204 * @throws IllegalArgumentException thrown if there is an exception +205 */ +206 @SuppressWarnings("static-access") +207privatevoid addStandardOptions(final Options options) throws IllegalArgumentException { +208final Option help = new Option(ARGUMENT.HELP_SHORT, ARGUMENT.HELP, false, +209"Print this message."); +210 +211final Option advancedHelp = OptionBuilder.withLongOpt(ARGUMENT.ADVANCED_HELP) +212 .withDescription("Print the advanced help message.").create(); +213 +214final Option version = new Option(ARGUMENT.VERSION_SHORT, ARGUMENT.VERSION, +215 false, "Print the version information."); +216 +217final Option noUpdate = new Option(ARGUMENT.DISABLE_AUTO_UPDATE_SHORT, ARGUMENT.DISABLE_AUTO_UPDATE, +218 false, "Disables the automatic updating of the CPE data."); +219 +220final Option appName = OptionBuilder.withArgName("name").hasArg().withLongOpt(ARGUMENT.APP_NAME) +221 .withDescription("The name of the application being scanned. This is a required argument.") +222 .create(ARGUMENT.APP_NAME_SHORT); +223 +224final Option path = OptionBuilder.withArgName("path").hasArg().withLongOpt(ARGUMENT.SCAN) +225 .withDescription("The path to scan - this option can be specified multiple times. Ant style" +226 + " paths are supported (e.g. path/**/*.jar).") +227 .create(ARGUMENT.SCAN_SHORT); +228 +229final Option excludes = OptionBuilder.withArgName("pattern").hasArg().withLongOpt(ARGUMENT.EXCLUDE) +230 .withDescription("Specify and exclusion pattern. This option can be specified multiple times" +231 + " and it accepts Ant style excludsions.") +232 .create(); +233 +234final Option props = OptionBuilder.withArgName("file").hasArg().withLongOpt(ARGUMENT.PROP) +235 .withDescription("A property file to load.") +236 .create(ARGUMENT.PROP_SHORT); +237 +238final Option out = OptionBuilder.withArgName("path").hasArg().withLongOpt(ARGUMENT.OUT) +239 .withDescription("The folder to write reports to. This defaults to the current directory. " +240 + "It is possible to set this to a specific file name if the format argument is not set to ALL.") +241 .create(ARGUMENT.OUT_SHORT); 242 -243final OptionGroup exog = new OptionGroup(); -244 exog.addOption(excludes); -245 -246 options.addOptionGroup(og) -247 .addOptionGroup(exog) -248 .addOption(out) -249 .addOption(outputFormat) -250 .addOption(appName) -251 .addOption(version) -252 .addOption(help) -253 .addOption(advancedHelp) -254 .addOption(noUpdate) -255 .addOption(props) -256 .addOption(verboseLog) -257 .addOption(suppressionFile); -258 } -259 -260/** -261 * Adds the advanced command line options to the given options collection. These are split out for purposes of being able to -262 * display two different help messages. -263 * -264 * @param options a collection of command line arguments -265 * @throws IllegalArgumentException thrown if there is an exception -266 */ -267 @SuppressWarnings("static-access") -268privatevoid addAdvancedOptions(final Options options) throws IllegalArgumentException { -269 -270final Option updateOnly = OptionBuilder.withLongOpt(ARGUMENT.UPDATE_ONLY) -271 .withDescription("Only update the local NVD data cache; no scan will be executed.").create(); -272 -273final Option data = OptionBuilder.withArgName("path").hasArg().withLongOpt(ARGUMENT.DATA_DIRECTORY) -274 .withDescription("The location of the H2 Database file. This option should generally not be set.") -275 .create(ARGUMENT.DATA_DIRECTORY_SHORT); -276 -277final Option connectionTimeout = OptionBuilder.withArgName("timeout").hasArg().withLongOpt(ARGUMENT.CONNECTION_TIMEOUT) -278 .withDescription("The connection timeout (in milliseconds) to use when downloading resources.") -279 .create(ARGUMENT.CONNECTION_TIMEOUT_SHORT); +243final Option outputFormat = OptionBuilder.withArgName("format").hasArg().withLongOpt(ARGUMENT.OUTPUT_FORMAT) +244 .withDescription("The output format to write to (XML, HTML, VULN, ALL). The default is HTML.") +245 .create(ARGUMENT.OUTPUT_FORMAT_SHORT); +246 +247final Option verboseLog = OptionBuilder.withArgName("file").hasArg().withLongOpt(ARGUMENT.VERBOSE_LOG) +248 .withDescription("The file path to write verbose logging information.") +249 .create(ARGUMENT.VERBOSE_LOG_SHORT); +250 +251final Option symLinkDepth = OptionBuilder.withArgName("depth").hasArg().withLongOpt(ARGUMENT.SYM_LINK_DEPTH) +252 .withDescription("Sets how deep nested symbolic links will be followed; 0 indicates symbolic links will not be followed.") +253 .create(); +254 +255final Option suppressionFile = OptionBuilder.withArgName("file").hasArg().withLongOpt(ARGUMENT.SUPPRESSION_FILE) +256 .withDescription("The file path to the suppression XML file.") +257 .create(); +258 +259//This is an option group because it can be specified more then once. +260final OptionGroup og = new OptionGroup(); +261 og.addOption(path); +262 +263final OptionGroup exog = new OptionGroup(); +264 exog.addOption(excludes); +265 +266 options.addOptionGroup(og) +267 .addOptionGroup(exog) +268 .addOption(out) +269 .addOption(outputFormat) +270 .addOption(appName) +271 .addOption(version) +272 .addOption(help) +273 .addOption(advancedHelp) +274 .addOption(noUpdate) +275 .addOption(symLinkDepth) +276 .addOption(props) +277 .addOption(verboseLog) +278 .addOption(suppressionFile); +279 } 280 -281final Option proxyServer = OptionBuilder.withArgName("server").hasArg().withLongOpt(ARGUMENT.PROXY_SERVER) -282 .withDescription("The proxy server to use when downloading resources.") -283 .create(); -284 -285final Option proxyPort = OptionBuilder.withArgName("port").hasArg().withLongOpt(ARGUMENT.PROXY_PORT) -286 .withDescription("The proxy port to use when downloading resources.") -287 .create(); -288 -289final Option proxyUsername = OptionBuilder.withArgName("user").hasArg().withLongOpt(ARGUMENT.PROXY_USERNAME) -290 .withDescription("The proxy username to use when downloading resources.") -291 .create(); -292 -293final Option proxyPassword = OptionBuilder.withArgName("pass").hasArg().withLongOpt(ARGUMENT.PROXY_PASSWORD) -294 .withDescription("The proxy password to use when downloading resources.") -295 .create(); -296 -297final Option connectionString = OptionBuilder.withArgName("connStr").hasArg().withLongOpt(ARGUMENT.CONNECTION_STRING) -298 .withDescription("The connection string to the database.") -299 .create(); -300 -301final Option dbUser = OptionBuilder.withArgName("user").hasArg().withLongOpt(ARGUMENT.DB_NAME) -302 .withDescription("The username used to connect to the database.") -303 .create(); -304 -305final Option dbPassword = OptionBuilder.withArgName("password").hasArg().withLongOpt(ARGUMENT.DB_PASSWORD) -306 .withDescription("The password for connecting to the database.") -307 .create(); -308 -309final Option dbDriver = OptionBuilder.withArgName("driver").hasArg().withLongOpt(ARGUMENT.DB_DRIVER) -310 .withDescription("The database driver name.") -311 .create(); -312 -313final Option dbDriverPath = OptionBuilder.withArgName("path").hasArg().withLongOpt(ARGUMENT.DB_DRIVER_PATH) -314 .withDescription("The path to the database driver; note, this does not need to be set unless the JAR is outside of the classpath.") -315 .create(); -316 -317final Option disableJarAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_JAR) -318 .withDescription("Disable the Jar Analyzer.") -319 .create(); -320final Option disableArchiveAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_ARCHIVE) -321 .withDescription("Disable the Archive Analyzer.") -322 .create(); -323final Option disableNuspecAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_NUSPEC) -324 .withDescription("Disable the Nuspec Analyzer.") -325 .create(); +281/** +282 * Adds the advanced command line options to the given options collection. These are split out for purposes of being able to +283 * display two different help messages. +284 * +285 * @param options a collection of command line arguments +286 * @throws IllegalArgumentException thrown if there is an exception +287 */ +288 @SuppressWarnings("static-access") +289privatevoid addAdvancedOptions(final Options options) throws IllegalArgumentException { +290 +291final Option cve12Base = OptionBuilder.withArgName("url").hasArg().withLongOpt(ARGUMENT.CVE_BASE_12) +292 .withDescription("Base URL for each year’s CVE 1.2, the %d will be replaced with the year. ") +293 .create(); +294 +295final Option cve20Base = OptionBuilder.withArgName("url").hasArg().withLongOpt(ARGUMENT.CVE_BASE_20) +296 .withDescription("Base URL for each year’s CVE 2.0, the %d will be replaced with the year.") +297 .create(); +298 +299final Option cve12Modified = OptionBuilder.withArgName("url").hasArg().withLongOpt(ARGUMENT.CVE_MOD_12) +300 .withDescription("URL for the modified CVE 1.2.") +301 .create(); +302 +303final Option cve20Modified = OptionBuilder.withArgName("url").hasArg().withLongOpt(ARGUMENT.CVE_MOD_20) +304 .withDescription("URL for the modified CVE 2.0.") +305 .create(); +306 +307final Option updateOnly = OptionBuilder.withLongOpt(ARGUMENT.UPDATE_ONLY) +308 .withDescription("Only update the local NVD data cache; no scan will be executed.").create(); +309 +310final Option data = OptionBuilder.withArgName("path").hasArg().withLongOpt(ARGUMENT.DATA_DIRECTORY) +311 .withDescription("The location of the H2 Database file. This option should generally not be set.") +312 .create(ARGUMENT.DATA_DIRECTORY_SHORT); +313 +314final Option nexusUrl = OptionBuilder.withArgName("url").hasArg().withLongOpt(ARGUMENT.NEXUS_URL) +315 .withDescription("The url to the Nexus Server's REST API Endpoint (http://domain/nexus/service/local). " +316 + "If not set the Nexus Analyzer will be disabled.").create(); +317 +318final Option nexusUsesProxy = OptionBuilder.withArgName("true/false").hasArg().withLongOpt(ARGUMENT.NEXUS_USES_PROXY) +319 .withDescription("Whether or not the configured proxy should be used when connecting to Nexus.") +320 .create(); +321 +322final Option additionalZipExtensions = OptionBuilder.withArgName("extensions").hasArg() +323 .withLongOpt(ARGUMENT.ADDITIONAL_ZIP_EXTENSIONS) +324 .withDescription("A comma separated list of additional extensions to be scanned as ZIP files " +325 + "(ZIP, EAR, WAR are already treated as zip files)").create(); 326 -327final Option disableAssemblyAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_ASSEMBLY) -328 .withDescription("Disable the .NET Assembly Analyzer.") +327final Option pathToMono = OptionBuilder.withArgName("path").hasArg().withLongOpt(ARGUMENT.PATH_TO_MONO) +328 .withDescription("The path to Mono for .NET Assembly analysis on non-windows systems.") 329 .create(); 330 -331final Option disablePythonDistributionAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_PY_DIST) -332 .withDescription("Disable the Python Distribution Analyzer.").create(); -333 -334final Option disablePythonPackageAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_PY_PKG) -335 .withDescription("Disable the Python Package Analyzer.").create(); -336 -337final Option disableCentralAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_CENTRAL) -338 .withDescription("Disable the Central Analyzer. If this analyzer is disabled it is likely you also want to disable " -339 + "the Nexus Analyzer.") -340 .create(); -341 -342final Option disableNexusAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_NEXUS) -343 .withDescription("Disable the Nexus Analyzer.") -344 .create(); -345 -346final Option nexusUrl = OptionBuilder.withArgName("url").hasArg().withLongOpt(ARGUMENT.NEXUS_URL) -347 .withDescription("The url to the Nexus Server's REST API Endpoint (http://domain/nexus/service/local). " -348 + "If not set the Nexus Analyzer will be disabled.") -349 .create(); -350 -351final Option nexusUsesProxy = OptionBuilder.withArgName("true/false").hasArg().withLongOpt(ARGUMENT.NEXUS_USES_PROXY) -352 .withDescription("Whether or not the configured proxy should be used when connecting to Nexus.") -353 .create(); -354 -355final Option additionalZipExtensions = OptionBuilder.withArgName("extensions").hasArg() -356 .withLongOpt(ARGUMENT.ADDITIONAL_ZIP_EXTENSIONS) -357 .withDescription("A comma separated list of additional extensions to be scanned as ZIP files " -358 + "(ZIP, EAR, WAR are already treated as zip files)") -359 .create(); -360 -361final Option pathToMono = OptionBuilder.withArgName("path").hasArg().withLongOpt(ARGUMENT.PATH_TO_MONO) -362 .withDescription("The path to Mono for .NET Assembly analysis on non-windows systems.") -363 .create(); -364 -365 options.addOption(updateOnly) -366 .addOption(proxyPort) -367 .addOption(proxyServer) -368 .addOption(proxyUsername) -369 .addOption(proxyPassword) -370 .addOption(connectionTimeout) -371 .addOption(connectionString) -372 .addOption(dbUser) -373 .addOption(data) -374 .addOption(dbPassword) -375 .addOption(dbDriver) -376 .addOption(dbDriverPath) -377 .addOption(disableJarAnalyzer) -378 .addOption(disableArchiveAnalyzer) -379 .addOption(disableAssemblyAnalyzer) -380 .addOption(disablePythonDistributionAnalyzer) -381 .addOption(disablePythonPackageAnalyzer) -382 .addOption(disableNuspecAnalyzer) -383 .addOption(disableCentralAnalyzer) -384 .addOption(disableNexusAnalyzer) -385 .addOption(nexusUrl) -386 .addOption(nexusUsesProxy) -387 .addOption(additionalZipExtensions) -388 .addOption(pathToMono); -389 } -390 -391/** -392 * Adds the deprecated command line options to the given options collection. These are split out for purposes of not including -393 * them in the help message. We need to add the deprecated options so as not to break existing scripts. -394 * -395 * @param options a collection of command line arguments -396 * @throws IllegalArgumentException thrown if there is an exception -397 */ -398 @SuppressWarnings("static-access") -399privatevoid addDeprecatedOptions(final Options options) throws IllegalArgumentException { -400 -401final Option proxyServer = OptionBuilder.withArgName("url").hasArg().withLongOpt(ARGUMENT.PROXY_URL) -402 .withDescription("The proxy url argument is deprecated, use proxyserver instead.") -403 .create(); -404 -405 options.addOption(proxyServer); -406 } -407 -408/** -409 * Determines if the 'version' command line argument was passed in. -410 * -411 * @return whether or not the 'version' command line argument was passed in -412 */ -413publicboolean isGetVersion() { -414return (line != null) && line.hasOption(ARGUMENT.VERSION); -415 } -416 -417/** -418 * Determines if the 'help' command line argument was passed in. -419 * -420 * @return whether or not the 'help' command line argument was passed in -421 */ -422publicboolean isGetHelp() { -423return (line != null) && line.hasOption(ARGUMENT.HELP); -424 } -425 -426/** -427 * Determines if the 'scan' command line argument was passed in. -428 * -429 * @return whether or not the 'scan' command line argument was passed in -430 */ -431publicboolean isRunScan() { -432return (line != null) && isValid && line.hasOption(ARGUMENT.SCAN); -433 } -434 -435/** -436 * Returns true if the disableJar command line argument was specified. -437 * -438 * @return true if the disableJar command line argument was specified; otherwise false -439 */ -440publicboolean isJarDisabled() { -441return (line != null) && line.hasOption(ARGUMENT.DISABLE_JAR); -442 } +331final Option connectionTimeout = OptionBuilder.withArgName("timeout").hasArg().withLongOpt(ARGUMENT.CONNECTION_TIMEOUT) +332 .withDescription("The connection timeout (in milliseconds) to use when downloading resources.") +333 .create(ARGUMENT.CONNECTION_TIMEOUT_SHORT); +334 +335final Option proxyServer = OptionBuilder.withArgName("server").hasArg().withLongOpt(ARGUMENT.PROXY_SERVER) +336 .withDescription("The proxy server to use when downloading resources.").create(); +337 +338final Option proxyPort = OptionBuilder.withArgName("port").hasArg().withLongOpt(ARGUMENT.PROXY_PORT) +339 .withDescription("The proxy port to use when downloading resources.").create(); +340 +341final Option proxyUsername = OptionBuilder.withArgName("user").hasArg().withLongOpt(ARGUMENT.PROXY_USERNAME) +342 .withDescription("The proxy username to use when downloading resources.").create(); +343 +344final Option proxyPassword = OptionBuilder.withArgName("pass").hasArg().withLongOpt(ARGUMENT.PROXY_PASSWORD) +345 .withDescription("The proxy password to use when downloading resources.").create(); +346 +347final Option connectionString = OptionBuilder.withArgName("connStr").hasArg().withLongOpt(ARGUMENT.CONNECTION_STRING) +348 .withDescription("The connection string to the database.").create(); +349 +350final Option dbUser = OptionBuilder.withArgName("user").hasArg().withLongOpt(ARGUMENT.DB_NAME) +351 .withDescription("The username used to connect to the database.").create(); +352 +353final Option dbPassword = OptionBuilder.withArgName("password").hasArg().withLongOpt(ARGUMENT.DB_PASSWORD) +354 .withDescription("The password for connecting to the database.").create(); +355 +356final Option dbDriver = OptionBuilder.withArgName("driver").hasArg().withLongOpt(ARGUMENT.DB_DRIVER) +357 .withDescription("The database driver name.").create(); +358 +359final Option dbDriverPath = OptionBuilder.withArgName("path").hasArg().withLongOpt(ARGUMENT.DB_DRIVER_PATH) +360 .withDescription("The path to the database driver; note, this does not need to be set unless the JAR is outside of the classpath.") +361 .create(); +362 +363final Option disableJarAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_JAR) +364 .withDescription("Disable the Jar Analyzer.").create(); +365 +366final Option disableArchiveAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_ARCHIVE) +367 .withDescription("Disable the Archive Analyzer.").create(); +368 +369final Option disableNuspecAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_NUSPEC) +370 .withDescription("Disable the Nuspec Analyzer.").create(); +371 +372final Option disableAssemblyAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_ASSEMBLY) +373 .withDescription("Disable the .NET Assembly Analyzer.").create(); +374 +375final Option disablePythonDistributionAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_PY_DIST) +376 .withDescription("Disable the Python Distribution Analyzer.").create(); +377 +378final Option disablePythonPackageAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_PY_PKG) +379 .withDescription("Disable the Python Package Analyzer.").create(); +380 +381final Option disableAutoconfAnalyzer = OptionBuilder +382 .withLongOpt(ARGUMENT.DISABLE_AUTOCONF) +383 .withDescription("Disable the Autoconf Analyzer.").create(); +384 +385final Option disableOpenSSLAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_OPENSSL) +386 .withDescription("Disable the OpenSSL Analyzer.").create(); +387final Option disableCmakeAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_CMAKE). +388 withDescription("Disable the Cmake Analyzer.").create(); +389 +390final Option disableCentralAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_CENTRAL) +391 .withDescription("Disable the Central Analyzer. If this analyzer is disabled it is likely you also want to disable " +392 + "the Nexus Analyzer.").create(); +393 +394final Option disableNexusAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_NEXUS) +395 .withDescription("Disable the Nexus Analyzer.").create(); +396 +397 options.addOption(updateOnly) +398 .addOption(cve12Base) +399 .addOption(cve20Base) +400 .addOption(cve12Modified) +401 .addOption(cve20Modified) +402 .addOption(proxyPort) +403 .addOption(proxyServer) +404 .addOption(proxyUsername) +405 .addOption(proxyPassword) +406 .addOption(connectionTimeout) +407 .addOption(connectionString) +408 .addOption(dbUser) +409 .addOption(data) +410 .addOption(dbPassword) +411 .addOption(dbDriver) +412 .addOption(dbDriverPath) +413 .addOption(disableJarAnalyzer) +414 .addOption(disableArchiveAnalyzer) +415 .addOption(disableAssemblyAnalyzer) +416 .addOption(disablePythonDistributionAnalyzer) +417 .addOption(disableCmakeAnalyzer) +418 .addOption(disablePythonPackageAnalyzer) +419 .addOption(disableAutoconfAnalyzer) +420 .addOption(disableOpenSSLAnalyzer) +421 .addOption(disableNuspecAnalyzer) +422 .addOption(disableCentralAnalyzer) +423 .addOption(disableNexusAnalyzer) +424 .addOption(nexusUrl) +425 .addOption(nexusUsesProxy) +426 .addOption(additionalZipExtensions) +427 .addOption(pathToMono); +428 } +429 +430/** +431 * Adds the deprecated command line options to the given options collection. These are split out for purposes of not including +432 * them in the help message. We need to add the deprecated options so as not to break existing scripts. +433 * +434 * @param options a collection of command line arguments +435 * @throws IllegalArgumentException thrown if there is an exception +436 */ +437 @SuppressWarnings({"static-access", "deprecation"}) +438privatevoid addDeprecatedOptions(final Options options) throws IllegalArgumentException { +439 +440final Option proxyServer = OptionBuilder.withArgName("url").hasArg().withLongOpt(ARGUMENT.PROXY_URL) +441 .withDescription("The proxy url argument is deprecated, use proxyserver instead.") +442 .create(); 443 -444/** -445 * Returns true if the disableArchive command line argument was specified. -446 * -447 * @return true if the disableArchive command line argument was specified; otherwise false -448 */ -449publicboolean isArchiveDisabled() { -450return (line != null) && line.hasOption(ARGUMENT.DISABLE_ARCHIVE); -451 } -452 -453/** -454 * Returns true if the disableNuspec command line argument was specified. -455 * -456 * @return true if the disableNuspec command line argument was specified; otherwise false -457 */ -458publicboolean isNuspecDisabled() { -459return (line != null) && line.hasOption(ARGUMENT.DISABLE_NUSPEC); -460 } -461 -462/** -463 * Returns true if the disableAssembly command line argument was specified. -464 * -465 * @return true if the disableAssembly command line argument was specified; otherwise false -466 */ -467publicboolean isAssemblyDisabled() { -468return (line != null) && line.hasOption(ARGUMENT.DISABLE_ASSEMBLY); -469 } -470 -471/** -472 * Returns true if the disablePyDist command line argument was specified. -473 * -474 * @return true if the disablePyDist command line argument was specified; otherwise false -475 */ -476publicboolean isPythonDistributionDisabled() { -477return (line != null) && line.hasOption(ARGUMENT.DISABLE_PY_DIST); -478 } -479 -480/** -481 * Returns true if the disablePyPkg command line argument was specified. -482 * -483 * @return true if the disablePyPkg command line argument was specified; otherwise false -484 */ -485publicboolean isPythonPackageDisabled() { -486return (line != null) && line.hasOption(ARGUMENT.DISABLE_PY_PKG); -487 } -488 -489/** -490 * Returns true if the disableNexus command line argument was specified. -491 * -492 * @return true if the disableNexus command line argument was specified; otherwise false -493 */ -494publicboolean isNexusDisabled() { -495return (line != null) && line.hasOption(ARGUMENT.DISABLE_NEXUS); -496 } -497 -498/** -499 * Returns true if the disableCentral command line argument was specified. -500 * -501 * @return true if the disableCentral command line argument was specified; otherwise false -502 */ -503publicboolean isCentralDisabled() { -504return (line != null) && line.hasOption(ARGUMENT.DISABLE_CENTRAL); -505 } -506 -507/** -508 * Returns the url to the nexus server if one was specified. -509 * -510 * @return the url to the nexus server; if none was specified this will return null; -511 */ -512public String getNexusUrl() { -513if (line == null || !line.hasOption(ARGUMENT.NEXUS_URL)) { -514returnnull; -515 } else { -516return line.getOptionValue(ARGUMENT.NEXUS_URL); -517 } -518 } -519 -520/** -521 * Returns true if the Nexus Analyzer should use the configured proxy to connect to Nexus; otherwise false is returned. -522 * -523 * @return true if the Nexus Analyzer should use the configured proxy to connect to Nexus; otherwise false -524 */ -525publicboolean isNexusUsesProxy() { -526// If they didn't specify whether Nexus needs to use the proxy, we should -527// still honor the property if it's set. -528if (line == null || !line.hasOption(ARGUMENT.NEXUS_USES_PROXY)) { -529try { -530return Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_PROXY); -531 } catch (InvalidSettingException ise) { -532returntrue; -533 } -534 } else { -535return Boolean.parseBoolean(line.getOptionValue(ARGUMENT.NEXUS_USES_PROXY)); -536 } -537 } -538 -539/** -540 * Displays the command line help message to the standard output. +444 options.addOption(proxyServer); +445 } +446 +447/** +448 * Determines if the 'version' command line argument was passed in. +449 * +450 * @return whether or not the 'version' command line argument was passed in +451 */ +452publicboolean isGetVersion() { +453return (line != null) && line.hasOption(ARGUMENT.VERSION); +454 } +455 +456/** +457 * Determines if the 'help' command line argument was passed in. +458 * +459 * @return whether or not the 'help' command line argument was passed in +460 */ +461publicboolean isGetHelp() { +462return (line != null) && line.hasOption(ARGUMENT.HELP); +463 } +464 +465/** +466 * Determines if the 'scan' command line argument was passed in. +467 * +468 * @return whether or not the 'scan' command line argument was passed in +469 */ +470publicboolean isRunScan() { +471return (line != null) && isValid && line.hasOption(ARGUMENT.SCAN); +472 } +473 +474/** +475 * Returns the symbolic link depth (how deeply symbolic links will be followed). +476 * +477 * @return the symbolic link depth +478 */ +479publicint getSymLinkDepth() { +480int value = 0; +481try { +482 value = Integer.parseInt(line.getOptionValue(ARGUMENT.SYM_LINK_DEPTH, "0")); +483if (value < 0) { +484 value = 0; +485 } +486 } catch (NumberFormatException ex) { +487 LOGGER.debug("Symbolic link was not a number"); +488 } +489return value; +490 } +491 +492/** +493 * Returns true if the disableJar command line argument was specified. +494 * +495 * @return true if the disableJar command line argument was specified; otherwise false +496 */ +497publicboolean isJarDisabled() { +498return (line != null) && line.hasOption(ARGUMENT.DISABLE_JAR); +499 } +500 +501/** +502 * Returns true if the disableArchive command line argument was specified. +503 * +504 * @return true if the disableArchive command line argument was specified; otherwise false +505 */ +506publicboolean isArchiveDisabled() { +507return (line != null) && line.hasOption(ARGUMENT.DISABLE_ARCHIVE); +508 } +509 +510/** +511 * Returns true if the disableNuspec command line argument was specified. +512 * +513 * @return true if the disableNuspec command line argument was specified; otherwise false +514 */ +515publicboolean isNuspecDisabled() { +516return (line != null) && line.hasOption(ARGUMENT.DISABLE_NUSPEC); +517 } +518 +519/** +520 * Returns true if the disableAssembly command line argument was specified. +521 * +522 * @return true if the disableAssembly command line argument was specified; otherwise false +523 */ +524publicboolean isAssemblyDisabled() { +525return (line != null) && line.hasOption(ARGUMENT.DISABLE_ASSEMBLY); +526 } +527 +528/** +529 * Returns true if the disablePyDist command line argument was specified. +530 * +531 * @return true if the disablePyDist command line argument was specified; otherwise false +532 */ +533publicboolean isPythonDistributionDisabled() { +534return (line != null) && line.hasOption(ARGUMENT.DISABLE_PY_DIST); +535 } +536 +537/** +538 * Returns true if the disablePyPkg command line argument was specified. +539 * +540 * @return true if the disablePyPkg command line argument was specified; otherwise false541 */ -542publicvoid printHelp() { -543final HelpFormatter formatter = new HelpFormatter(); -544final Options options = new Options(); -545 addStandardOptions(options); -546if (line != null && line.hasOption(ARGUMENT.ADVANCED_HELP)) { -547 addAdvancedOptions(options); -548 } -549final String helpMsg = String.format("%n%s" -550 + " can be used to identify if there are any known CVE vulnerabilities in libraries utilized by an application. " -551 + "%s will automatically update required data from the Internet, such as the CVE and CPE data files from nvd.nist.gov.%n%n", -552 Settings.getString("application.name", "DependencyCheck"), -553 Settings.getString("application.name", "DependencyCheck")); +542publicboolean isPythonPackageDisabled() { +543return (line != null) && line.hasOption(ARGUMENT.DISABLE_PY_PKG); +544 } +545 +546/** +547 * Returns true if the disableCmake command line argument was specified. +548 * +549 * @return true if the disableCmake command line argument was specified; otherwise false +550 */ +551publicboolean isCmakeDisabled() { +552return (line != null) && line.hasOption(ARGUMENT.DISABLE_CMAKE); +553 } 554 -555 formatter.printHelp(Settings.getString("application.name", "DependencyCheck"), -556 helpMsg, -557 options, -558"", -559true); -560 } -561 -562/** -563 * Retrieves the file command line parameter(s) specified for the 'scan' argument. -564 * -565 * @return the file paths specified on the command line for scan -566 */ -567public String[] getScanFiles() { -568return line.getOptionValues(ARGUMENT.SCAN); -569 } -570 -571/** -572 * Retrieves the list of excluded file patterns specified by the 'exclude' argument. -573 * -574 * @return the excluded file patterns -575 */ -576public String[] getExcludeList() { -577return line.getOptionValues(ARGUMENT.EXCLUDE); -578 } -579 -580/** -581 * Returns the directory to write the reports to specified on the command line. -582 * -583 * @return the path to the reports directory. -584 */ -585public String getReportDirectory() { -586return line.getOptionValue(ARGUMENT.OUT, "."); -587 } -588 -589/** -590 * Returns the path to Mono for .NET Assembly analysis on non-windows systems. -591 * -592 * @return the path to Mono -593 */ -594public String getPathToMono() { -595return line.getOptionValue(ARGUMENT.PATH_TO_MONO); -596 } -597 -598/** -599 * Returns the output format specified on the command line. Defaults to HTML if no format was specified. -600 * -601 * @return the output format name. -602 */ -603public String getReportFormat() { -604return line.getOptionValue(ARGUMENT.OUTPUT_FORMAT, "HTML"); -605 } -606 -607/** -608 * Returns the application name specified on the command line. -609 * -610 * @return the application name. -611 */ -612public String getApplicationName() { -613return line.getOptionValue(ARGUMENT.APP_NAME); -614 } -615 -616/** -617 * Returns the connection timeout. -618 * -619 * @return the connection timeout -620 */ -621public String getConnectionTimeout() { -622return line.getOptionValue(ARGUMENT.CONNECTION_TIMEOUT); -623 } -624 -625/** -626 * Returns the proxy server. -627 * -628 * @return the proxy server -629 */ -630public String getProxyServer() { -631 -632 String server = line.getOptionValue(ARGUMENT.PROXY_SERVER); -633if (server == null) { -634 server = line.getOptionValue(ARGUMENT.PROXY_URL); -635if (server != null) { -636 LOGGER.warning("An old command line argument 'proxyurl' was detected; use proxyserver instead"); -637 } -638 } -639return server; -640 } -641 -642/** -643 * Returns the proxy port. -644 * -645 * @return the proxy port -646 */ -647public String getProxyPort() { -648return line.getOptionValue(ARGUMENT.PROXY_PORT); -649 } -650 -651/** -652 * Returns the proxy username. -653 * -654 * @return the proxy username -655 */ -656public String getProxyUsername() { -657return line.getOptionValue(ARGUMENT.PROXY_USERNAME); -658 } -659 -660/** -661 * Returns the proxy password. -662 * -663 * @return the proxy password -664 */ -665public String getProxyPassword() { -666return line.getOptionValue(ARGUMENT.PROXY_PASSWORD); -667 } -668 -669/** -670 * Get the value of dataDirectory. -671 * -672 * @return the value of dataDirectory -673 */ -674public String getDataDirectory() { -675return line.getOptionValue(ARGUMENT.DATA_DIRECTORY); -676 } -677 -678/** -679 * Returns the properties file specified on the command line. -680 * -681 * @return the properties file specified on the command line -682 */ -683public File getPropertiesFile() { -684final String path = line.getOptionValue(ARGUMENT.PROP); -685if (path != null) { -686returnnew File(path); -687 } -688returnnull; +555/** +556 * Returns true if the disableAutoconf command line argument was specified. +557 * +558 * @return true if the disableAutoconf command line argument was specified; otherwise false +559 */ +560publicboolean isAutoconfDisabled() { +561return (line != null) && line.hasOption(ARGUMENT.DISABLE_AUTOCONF); +562 } +563 +564/** +565 * Returns true if the disableNexus command line argument was specified. +566 * +567 * @return true if the disableNexus command line argument was specified; otherwise false +568 */ +569publicboolean isNexusDisabled() { +570return (line != null) && line.hasOption(ARGUMENT.DISABLE_NEXUS); +571 } +572 +573/** +574 * Returns true if the disableOpenSSL command line argument was specified. +575 * +576 * @return true if the disableOpenSSL command line argument was specified; otherwise false +577 */ +578publicboolean isOpenSSLDisabled() { +579return (line != null) && line.hasOption(ARGUMENT.DISABLE_OPENSSL); +580 } +581 +582/** +583 * Returns true if the disableCentral command line argument was specified. +584 * +585 * @return true if the disableCentral command line argument was specified; otherwise false +586 */ +587publicboolean isCentralDisabled() { +588return (line != null) && line.hasOption(ARGUMENT.DISABLE_CENTRAL); +589 } +590 +591/** +592 * Returns the url to the nexus server if one was specified. +593 * +594 * @return the url to the nexus server; if none was specified this will return null; +595 */ +596public String getNexusUrl() { +597if (line == null || !line.hasOption(ARGUMENT.NEXUS_URL)) { +598returnnull; +599 } else { +600return line.getOptionValue(ARGUMENT.NEXUS_URL); +601 } +602 } +603 +604/** +605 * Returns true if the Nexus Analyzer should use the configured proxy to connect to Nexus; otherwise false is returned. +606 * +607 * @return true if the Nexus Analyzer should use the configured proxy to connect to Nexus; otherwise false +608 */ +609publicboolean isNexusUsesProxy() { +610// If they didn't specify whether Nexus needs to use the proxy, we should +611// still honor the property if it's set. +612if (line == null || !line.hasOption(ARGUMENT.NEXUS_USES_PROXY)) { +613try { +614return Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_PROXY); +615 } catch (InvalidSettingException ise) { +616returntrue; +617 } +618 } else { +619return Boolean.parseBoolean(line.getOptionValue(ARGUMENT.NEXUS_USES_PROXY)); +620 } +621 } +622 +623/** +624 * Displays the command line help message to the standard output. +625 */ +626publicvoid printHelp() { +627final HelpFormatter formatter = new HelpFormatter(); +628final Options options = new Options(); +629 addStandardOptions(options); +630if (line != null && line.hasOption(ARGUMENT.ADVANCED_HELP)) { +631 addAdvancedOptions(options); +632 } +633final String helpMsg = String.format("%n%s" +634 + " can be used to identify if there are any known CVE vulnerabilities in libraries utilized by an application. " +635 + "%s will automatically update required data from the Internet, such as the CVE and CPE data files from nvd.nist.gov.%n%n", +636 Settings.getString("application.name", "DependencyCheck"), +637 Settings.getString("application.name", "DependencyCheck")); +638 +639 formatter.printHelp(Settings.getString("application.name", "DependencyCheck"), +640 helpMsg, +641 options, +642"", +643true); +644 } +645 +646/** +647 * Retrieves the file command line parameter(s) specified for the 'scan' argument. +648 * +649 * @return the file paths specified on the command line for scan +650 */ +651public String[] getScanFiles() { +652return line.getOptionValues(ARGUMENT.SCAN); +653 } +654 +655/** +656 * Retrieves the list of excluded file patterns specified by the 'exclude' argument. +657 * +658 * @return the excluded file patterns +659 */ +660public String[] getExcludeList() { +661return line.getOptionValues(ARGUMENT.EXCLUDE); +662 } +663 +664/** +665 * Returns the directory to write the reports to specified on the command line. +666 * +667 * @return the path to the reports directory. +668 */ +669public String getReportDirectory() { +670return line.getOptionValue(ARGUMENT.OUT, "."); +671 } +672 +673/** +674 * Returns the path to Mono for .NET Assembly analysis on non-windows systems. +675 * +676 * @return the path to Mono +677 */ +678public String getPathToMono() { +679return line.getOptionValue(ARGUMENT.PATH_TO_MONO); +680 } +681 +682/** +683 * Returns the output format specified on the command line. Defaults to HTML if no format was specified. +684 * +685 * @return the output format name. +686 */ +687public String getReportFormat() { +688return line.getOptionValue(ARGUMENT.OUTPUT_FORMAT, "HTML"); 689 } 690691/** -692 * Returns the path to the verbose log file. +692 * Returns the application name specified on the command line.693 * -694 * @return the path to the verbose log file +694 * @return the application name.695 */ -696public String getVerboseLog() { -697return line.getOptionValue(ARGUMENT.VERBOSE_LOG); +696public String getApplicationName() { +697return line.getOptionValue(ARGUMENT.APP_NAME); 698 } 699700/** -701 * Returns the path to the suppression file. +701 * Returns the base URL for the CVE 1.2 XMl file.702 * -703 * @return the path to the suppression file +703 * @return the URL to the CVE 1.2 XML file.704 */ -705public String getSuppressionFile() { -706return line.getOptionValue(ARGUMENT.SUPPRESSION_FILE); +705public String getBaseCve12Url() { +706return line.getOptionValue(ARGUMENT.CVE_BASE_12); 707 } 708709/** -710 * <p> -711 * Prints the manifest information to standard output.</p> -712 * <ul><li>Implementation-Title: ${pom.name}</li> -713 * <li>Implementation-Version: ${pom.version}</li></ul> -714 */ -715publicvoid printVersionInfo() { -716final String version = String.format("%s version %s", -717 Settings.getString(Settings.KEYS.APPLICATION_VAME, "dependency-check"), -718 Settings.getString(Settings.KEYS.APPLICATION_VERSION, "Unknown")); -719 System.out.println(version); -720 } -721 -722/** -723 * Checks if the auto update feature has been disabled. If it has been disabled via the command line this will return false. -724 * -725 * @return <code>true</code> if auto-update is allowed; otherwise <code>false</code> -726 */ -727publicboolean isAutoUpdate() { -728return (line == null) || !line.hasOption(ARGUMENT.DISABLE_AUTO_UPDATE); -729 } -730 -731/** -732 * Checks if the update only flag has been set. -733 * -734 * @return <code>true</code> if the update only flag has been set; otherwise <code>false</code>. -735 */ -736publicboolean isUpdateOnly() { -737return (line == null) || line.hasOption(ARGUMENT.UPDATE_ONLY); -738 } -739 -740/** -741 * Returns the database driver name if specified; otherwise null is returned. -742 * -743 * @return the database driver name if specified; otherwise null is returned -744 */ -745public String getDatabaseDriverName() { -746return line.getOptionValue(ARGUMENT.DB_DRIVER); -747 } -748 -749/** -750 * Returns the database driver path if specified; otherwise null is returned. -751 * -752 * @return the database driver name if specified; otherwise null is returned -753 */ -754public String getDatabaseDriverPath() { -755return line.getOptionValue(ARGUMENT.DB_DRIVER_PATH); -756 } -757 -758/** -759 * Returns the database connection string if specified; otherwise null is returned. -760 * -761 * @return the database connection string if specified; otherwise null is returned -762 */ -763public String getConnectionString() { -764return line.getOptionValue(ARGUMENT.CONNECTION_STRING); -765 } -766 -767/** -768 * Returns the database database user name if specified; otherwise null is returned. -769 * -770 * @return the database database user name if specified; otherwise null is returned -771 */ -772public String getDatabaseUser() { -773return line.getOptionValue(ARGUMENT.DB_NAME); -774 } -775 -776/** -777 * Returns the database database password if specified; otherwise null is returned. -778 * -779 * @return the database database password if specified; otherwise null is returned -780 */ -781public String getDatabasePassword() { -782return line.getOptionValue(ARGUMENT.DB_PASSWORD); -783 } -784 -785/** -786 * Returns the additional Extensions if specified; otherwise null is returned. -787 * -788 * @return the additional Extensions; otherwise null is returned -789 */ -790public String getAdditionalZipExtensions() { -791return line.getOptionValue(ARGUMENT.ADDITIONAL_ZIP_EXTENSIONS); -792 } -793 -794/** -795 * A collection of static final strings that represent the possible command line arguments. -796 */ -797publicstaticclassARGUMENT { +710 * Returns the base URL for the CVE 2.0 XMl file. +711 * +712 * @return the URL to the CVE 2.0 XML file. +713 */ +714public String getBaseCve20Url() { +715return line.getOptionValue(ARGUMENT.CVE_BASE_20); +716 } +717 +718/** +719 * Returns the URL for the modified CVE 1.2 XMl file. +720 * +721 * @return the URL to the modified CVE 1.2 XML file. +722 */ +723public String getModifiedCve12Url() { +724return line.getOptionValue(ARGUMENT.CVE_MOD_12); +725 } +726 +727/** +728 * Returns the URL for the modified CVE 2.0 XMl file. +729 * +730 * @return the URL to the modified CVE 2.0 XML file. +731 */ +732public String getModifiedCve20Url() { +733return line.getOptionValue(ARGUMENT.CVE_MOD_20); +734 } +735 +736/** +737 * Returns the connection timeout. +738 * +739 * @return the connection timeout +740 */ +741public String getConnectionTimeout() { +742return line.getOptionValue(ARGUMENT.CONNECTION_TIMEOUT); +743 } +744 +745/** +746 * Returns the proxy server. +747 * +748 * @return the proxy server +749 */ +750 @SuppressWarnings("deprecation") +751public String getProxyServer() { +752 +753 String server = line.getOptionValue(ARGUMENT.PROXY_SERVER); +754if (server == null) { +755 server = line.getOptionValue(ARGUMENT.PROXY_URL); +756if (server != null) { +757 LOGGER.warn("An old command line argument 'proxyurl' was detected; use proxyserver instead"); +758 } +759 } +760return server; +761 } +762 +763/** +764 * Returns the proxy port. +765 * +766 * @return the proxy port +767 */ +768public String getProxyPort() { +769return line.getOptionValue(ARGUMENT.PROXY_PORT); +770 } +771 +772/** +773 * Returns the proxy username. +774 * +775 * @return the proxy username +776 */ +777public String getProxyUsername() { +778return line.getOptionValue(ARGUMENT.PROXY_USERNAME); +779 } +780 +781/** +782 * Returns the proxy password. +783 * +784 * @return the proxy password +785 */ +786public String getProxyPassword() { +787return line.getOptionValue(ARGUMENT.PROXY_PASSWORD); +788 } +789 +790/** +791 * Get the value of dataDirectory. +792 * +793 * @return the value of dataDirectory +794 */ +795public String getDataDirectory() { +796return line.getOptionValue(ARGUMENT.DATA_DIRECTORY); +797 } 798 -799/** -800 * The long CLI argument name specifying the directory/file to scan. -801 */ -802publicstaticfinal String SCAN = "scan"; -803/** -804 * The short CLI argument name specifying the directory/file to scan. -805 */ -806publicstaticfinal String SCAN_SHORT = "s"; -807/** -808 * The long CLI argument name specifying that the CPE/CVE/etc. data should not be automatically updated. -809 */ -810publicstaticfinal String DISABLE_AUTO_UPDATE = "noupdate"; -811/** -812 * The short CLI argument name specifying that the CPE/CVE/etc. data should not be automatically updated. -813 */ -814publicstaticfinal String DISABLE_AUTO_UPDATE_SHORT = "n"; -815/** -816 * The long CLI argument name specifying that only the update phase should be executed; no scan should be run. -817 */ -818publicstaticfinal String UPDATE_ONLY = "updateonly"; -819/** -820 * The long CLI argument name specifying the directory to write the reports to. -821 */ -822publicstaticfinal String OUT = "out"; -823/** -824 * The short CLI argument name specifying the directory to write the reports to. -825 */ -826publicstaticfinal String OUT_SHORT = "o"; -827/** -828 * The long CLI argument name specifying the output format to write the reports to. -829 */ -830publicstaticfinal String OUTPUT_FORMAT = "format"; -831/** -832 * The short CLI argument name specifying the output format to write the reports to. -833 */ -834publicstaticfinal String OUTPUT_FORMAT_SHORT = "f"; -835/** -836 * The long CLI argument name specifying the name of the application to be scanned. -837 */ -838publicstaticfinal String APP_NAME = "app"; -839/** -840 * The short CLI argument name specifying the name of the application to be scanned. -841 */ -842publicstaticfinal String APP_NAME_SHORT = "a"; -843/** -844 * The long CLI argument name asking for help. -845 */ -846publicstaticfinal String HELP = "help"; -847/** -848 * The long CLI argument name asking for advanced help. -849 */ -850publicstaticfinal String ADVANCED_HELP = "advancedHelp"; -851/** -852 * The short CLI argument name asking for help. -853 */ -854publicstaticfinal String HELP_SHORT = "h"; -855/** -856 * The long CLI argument name asking for the version. -857 */ -858publicstaticfinal String VERSION_SHORT = "v"; -859/** -860 * The short CLI argument name asking for the version. -861 */ -862publicstaticfinal String VERSION = "version"; -863/** -864 * The CLI argument name indicating the proxy port. -865 */ -866publicstaticfinal String PROXY_PORT = "proxyport"; -867/** -868 * The CLI argument name indicating the proxy server. -869 */ -870publicstaticfinal String PROXY_SERVER = "proxyserver"; -871/** -872 * The CLI argument name indicating the proxy url. -873 * -874 * @deprecated use {@link org.owasp.dependencycheck.cli.CliParser.ArgumentName#PROXY_SERVER} instead -875 */ -876 @Deprecated -877publicstaticfinal String PROXY_URL = "proxyurl"; -878/** -879 * The CLI argument name indicating the proxy username. -880 */ -881publicstaticfinal String PROXY_USERNAME = "proxyuser"; -882/** -883 * The CLI argument name indicating the proxy password. -884 */ -885publicstaticfinal String PROXY_PASSWORD = "proxypass"; -886/** -887 * The short CLI argument name indicating the connection timeout. -888 */ -889publicstaticfinal String CONNECTION_TIMEOUT_SHORT = "c"; -890/** -891 * The CLI argument name indicating the connection timeout. -892 */ -893publicstaticfinal String CONNECTION_TIMEOUT = "connectiontimeout"; -894/** -895 * The short CLI argument name for setting the location of an additional properties file. -896 */ -897publicstaticfinal String PROP_SHORT = "P"; -898/** -899 * The CLI argument name for setting the location of an additional properties file. -900 */ -901publicstaticfinal String PROP = "propertyfile"; -902/** -903 * The CLI argument name for setting the location of the data directory. -904 */ -905publicstaticfinal String DATA_DIRECTORY = "data"; -906/** -907 * The short CLI argument name for setting the location of the data directory. -908 */ -909publicstaticfinal String DATA_DIRECTORY_SHORT = "d"; -910/** -911 * The CLI argument name for setting the location of the data directory. -912 */ -913publicstaticfinal String VERBOSE_LOG = "log"; -914/** -915 * The short CLI argument name for setting the location of the data directory. -916 */ -917publicstaticfinal String VERBOSE_LOG_SHORT = "l"; -918/** -919 * The CLI argument name for setting the location of the suppression file. -920 */ -921publicstaticfinal String SUPPRESSION_FILE = "suppression"; -922/** -923 * Disables the Jar Analyzer. -924 */ -925publicstaticfinal String DISABLE_JAR = "disableJar"; -926/** -927 * Disables the Archive Analyzer. -928 */ -929publicstaticfinal String DISABLE_ARCHIVE = "disableArchive"; -930/** -931 * Disables the Python Distribution Analyzer. -932 */ -933publicstaticfinal String DISABLE_PY_DIST = "disablePyDist"; -934/** -935 * Disables the Python Package Analyzer. -936 */ -937publicstaticfinal String DISABLE_PY_PKG = "disablePyPkg"; -938/** -939 * Disables the Assembly Analyzer. -940 */ -941publicstaticfinal String DISABLE_ASSEMBLY = "disableAssembly"; -942/** -943 * Disables the Nuspec Analyzer. -944 */ -945publicstaticfinal String DISABLE_NUSPEC = "disableNuspec"; -946/** -947 * Disables the Central Analyzer. -948 */ -949publicstaticfinal String DISABLE_CENTRAL = "disableCentral"; -950/** -951 * Disables the Nexus Analyzer. -952 */ -953publicstaticfinal String DISABLE_NEXUS = "disableNexus"; -954/** -955 * The URL of the nexus server. -956 */ -957publicstaticfinal String NEXUS_URL = "nexus"; -958/** -959 * Whether or not the defined proxy should be used when connecting to Nexus. -960 */ -961publicstaticfinal String NEXUS_USES_PROXY = "nexusUsesProxy"; -962/** -963 * The CLI argument name for setting the connection string. -964 */ -965publicstaticfinal String CONNECTION_STRING = "connectionString"; -966/** -967 * The CLI argument name for setting the database user name. -968 */ -969publicstaticfinal String DB_NAME = "dbUser"; -970/** -971 * The CLI argument name for setting the database password. -972 */ -973publicstaticfinal String DB_PASSWORD = "dbPassword"; -974/** -975 * The CLI argument name for setting the database driver name. -976 */ -977publicstaticfinal String DB_DRIVER = "dbDriverName"; -978/** -979 * The CLI argument name for setting the path to the database driver; in case it is not on the class path. -980 */ -981publicstaticfinal String DB_DRIVER_PATH = "dbDriverPath"; -982/** -983 * The CLI argument name for setting the path to mono for .NET Assembly analysis on non-windows systems. -984 */ -985publicstaticfinal String PATH_TO_MONO = "mono"; -986/** -987 * The CLI argument name for setting extra extensions. -988 */ -989publicstaticfinal String ADDITIONAL_ZIP_EXTENSIONS = "zipExtensions"; -990/** -991 * Exclude path argument. -992 */ -993publicstaticfinal String EXCLUDE = "exclude"; -994 } -995 } +799/** +800 * Returns the properties file specified on the command line. +801 * +802 * @return the properties file specified on the command line +803 */ +804public File getPropertiesFile() { +805final String path = line.getOptionValue(ARGUMENT.PROP); +806if (path != null) { +807returnnew File(path); +808 } +809returnnull; +810 } +811 +812/** +813 * Returns the path to the verbose log file. +814 * +815 * @return the path to the verbose log file +816 */ +817public String getVerboseLog() { +818return line.getOptionValue(ARGUMENT.VERBOSE_LOG); +819 } +820 +821/** +822 * Returns the path to the suppression file. +823 * +824 * @return the path to the suppression file +825 */ +826public String getSuppressionFile() { +827return line.getOptionValue(ARGUMENT.SUPPRESSION_FILE); +828 } +829 +830/** +831 * <p> +832 * Prints the manifest information to standard output.</p> +833 * <ul><li>Implementation-Title: ${pom.name}</li> +834 * <li>Implementation-Version: ${pom.version}</li></ul> +835 */ +836publicvoid printVersionInfo() { +837final String version = String.format("%s version %s", +838 Settings.getString(Settings.KEYS.APPLICATION_VAME, "dependency-check"), +839 Settings.getString(Settings.KEYS.APPLICATION_VERSION, "Unknown")); +840 System.out.println(version); +841 } +842 +843/** +844 * Checks if the auto update feature has been disabled. If it has been disabled via the command line this will return false. +845 * +846 * @return <code>true</code> if auto-update is allowed; otherwise <code>false</code> +847 */ +848publicboolean isAutoUpdate() { +849return (line == null) || !line.hasOption(ARGUMENT.DISABLE_AUTO_UPDATE); +850 } +851 +852/** +853 * Checks if the update only flag has been set. +854 * +855 * @return <code>true</code> if the update only flag has been set; otherwise <code>false</code>. +856 */ +857publicboolean isUpdateOnly() { +858return (line == null) || line.hasOption(ARGUMENT.UPDATE_ONLY); +859 } +860 +861/** +862 * Returns the database driver name if specified; otherwise null is returned. +863 * +864 * @return the database driver name if specified; otherwise null is returned +865 */ +866public String getDatabaseDriverName() { +867return line.getOptionValue(ARGUMENT.DB_DRIVER); +868 } +869 +870/** +871 * Returns the database driver path if specified; otherwise null is returned. +872 * +873 * @return the database driver name if specified; otherwise null is returned +874 */ +875public String getDatabaseDriverPath() { +876return line.getOptionValue(ARGUMENT.DB_DRIVER_PATH); +877 } +878 +879/** +880 * Returns the database connection string if specified; otherwise null is returned. +881 * +882 * @return the database connection string if specified; otherwise null is returned +883 */ +884public String getConnectionString() { +885return line.getOptionValue(ARGUMENT.CONNECTION_STRING); +886 } +887 +888/** +889 * Returns the database database user name if specified; otherwise null is returned. +890 * +891 * @return the database database user name if specified; otherwise null is returned +892 */ +893public String getDatabaseUser() { +894return line.getOptionValue(ARGUMENT.DB_NAME); +895 } +896 +897/** +898 * Returns the database database password if specified; otherwise null is returned. +899 * +900 * @return the database database password if specified; otherwise null is returned +901 */ +902public String getDatabasePassword() { +903return line.getOptionValue(ARGUMENT.DB_PASSWORD); +904 } +905 +906/** +907 * Returns the additional Extensions if specified; otherwise null is returned. +908 * +909 * @return the additional Extensions; otherwise null is returned +910 */ +911public String getAdditionalZipExtensions() { +912return line.getOptionValue(ARGUMENT.ADDITIONAL_ZIP_EXTENSIONS); +913 } +914 +915/** +916 * A collection of static final strings that represent the possible command line arguments. +917 */ +918publicstaticclassARGUMENT { +919 +920/** +921 * The long CLI argument name specifying the directory/file to scan. +922 */ +923publicstaticfinal String SCAN = "scan"; +924/** +925 * The short CLI argument name specifying the directory/file to scan. +926 */ +927publicstaticfinal String SCAN_SHORT = "s"; +928/** +929 * The long CLI argument name specifying that the CPE/CVE/etc. data should not be automatically updated. +930 */ +931publicstaticfinal String DISABLE_AUTO_UPDATE = "noupdate"; +932/** +933 * The short CLI argument name specifying that the CPE/CVE/etc. data should not be automatically updated. +934 */ +935publicstaticfinal String DISABLE_AUTO_UPDATE_SHORT = "n"; +936/** +937 * The long CLI argument name specifying that only the update phase should be executed; no scan should be run. +938 */ +939publicstaticfinal String UPDATE_ONLY = "updateonly"; +940/** +941 * The long CLI argument name specifying the directory to write the reports to. +942 */ +943publicstaticfinal String OUT = "out"; +944/** +945 * The short CLI argument name specifying the directory to write the reports to. +946 */ +947publicstaticfinal String OUT_SHORT = "o"; +948/** +949 * The long CLI argument name specifying the output format to write the reports to. +950 */ +951publicstaticfinal String OUTPUT_FORMAT = "format"; +952/** +953 * The short CLI argument name specifying the output format to write the reports to. +954 */ +955publicstaticfinal String OUTPUT_FORMAT_SHORT = "f"; +956/** +957 * The long CLI argument name specifying the name of the application to be scanned. +958 */ +959publicstaticfinal String APP_NAME = "app"; +960/** +961 * The short CLI argument name specifying the name of the application to be scanned. +962 */ +963publicstaticfinal String APP_NAME_SHORT = "a"; +964/** +965 * The long CLI argument name asking for help. +966 */ +967publicstaticfinal String HELP = "help"; +968/** +969 * The long CLI argument name asking for advanced help. +970 */ +971publicstaticfinal String ADVANCED_HELP = "advancedHelp"; +972/** +973 * The short CLI argument name asking for help. +974 */ +975publicstaticfinal String HELP_SHORT = "h"; +976/** +977 * The long CLI argument name asking for the version. +978 */ +979publicstaticfinal String VERSION_SHORT = "v"; +980/** +981 * The short CLI argument name asking for the version. +982 */ +983publicstaticfinal String VERSION = "version"; +984/** +985 * The CLI argument name indicating the proxy port. +986 */ +987publicstaticfinal String PROXY_PORT = "proxyport"; +988/** +989 * The CLI argument name indicating the proxy server. +990 */ +991publicstaticfinal String PROXY_SERVER = "proxyserver"; +992/** +993 * The CLI argument name indicating the proxy url. +994 * +995 * @deprecated use {@link #PROXY_SERVER} instead +996 */ +997 @Deprecated +998publicstaticfinal String PROXY_URL = "proxyurl"; +999/** +1000 * The CLI argument name indicating the proxy username. +1001 */ +1002publicstaticfinal String PROXY_USERNAME = "proxyuser"; +1003/** +1004 * The CLI argument name indicating the proxy password. +1005 */ +1006publicstaticfinal String PROXY_PASSWORD = "proxypass"; +1007/** +1008 * The short CLI argument name indicating the connection timeout. +1009 */ +1010publicstaticfinal String CONNECTION_TIMEOUT_SHORT = "c"; +1011/** +1012 * The CLI argument name indicating the connection timeout. +1013 */ +1014publicstaticfinal String CONNECTION_TIMEOUT = "connectiontimeout"; +1015/** +1016 * The short CLI argument name for setting the location of an additional properties file. +1017 */ +1018publicstaticfinal String PROP_SHORT = "P"; +1019/** +1020 * The CLI argument name for setting the location of an additional properties file. +1021 */ +1022publicstaticfinal String PROP = "propertyfile"; +1023/** +1024 * The CLI argument name for setting the location of the data directory. +1025 */ +1026publicstaticfinal String DATA_DIRECTORY = "data"; +1027/** +1028 * The CLI argument name for setting the URL for the CVE Data Files. +1029 */ +1030publicstaticfinal String CVE_MOD_12 = "cveUrl12Modified"; +1031/** +1032 * The CLI argument name for setting the URL for the CVE Data Files. +1033 */ +1034publicstaticfinal String CVE_MOD_20 = "cveUrl20Modified"; +1035/** +1036 * The CLI argument name for setting the URL for the CVE Data Files. +1037 */ +1038publicstaticfinal String CVE_BASE_12 = "cveUrl12Base"; +1039/** +1040 * The CLI argument name for setting the URL for the CVE Data Files. +1041 */ +1042publicstaticfinal String CVE_BASE_20 = "cveUrl20Base"; +1043/** +1044 * The short CLI argument name for setting the location of the data directory. +1045 */ +1046publicstaticfinal String DATA_DIRECTORY_SHORT = "d"; +1047/** +1048 * The CLI argument name for setting the location of the data directory. +1049 */ +1050publicstaticfinal String VERBOSE_LOG = "log"; +1051/** +1052 * The short CLI argument name for setting the location of the data directory. +1053 */ +1054publicstaticfinal String VERBOSE_LOG_SHORT = "l"; +1055 +1056/** +1057 * The CLI argument name for setting the depth of symbolic links that will be followed. +1058 */ +1059publicstaticfinal String SYM_LINK_DEPTH = "symLink"; +1060/** +1061 * The CLI argument name for setting the location of the suppression file. +1062 */ +1063publicstaticfinal String SUPPRESSION_FILE = "suppression"; +1064/** +1065 * Disables the Jar Analyzer. +1066 */ +1067publicstaticfinal String DISABLE_JAR = "disableJar"; +1068/** +1069 * Disables the Archive Analyzer. +1070 */ +1071publicstaticfinal String DISABLE_ARCHIVE = "disableArchive"; +1072/** +1073 * Disables the Python Distribution Analyzer. +1074 */ +1075publicstaticfinal String DISABLE_PY_DIST = "disablePyDist"; +1076/** +1077 * Disables the Python Package Analyzer. +1078 */ +1079publicstaticfinal String DISABLE_PY_PKG = "disablePyPkg"; +1080/** +1081 * Disables the Autoconf Analyzer. +1082 */ +1083publicstaticfinal String DISABLE_AUTOCONF = "disableAutoconf"; +1084/** +1085 * Disables the Cmake Analyzer. +1086 */ +1087publicstaticfinal String DISABLE_CMAKE = "disableCmake"; +1088/** +1089 * Disables the Assembly Analyzer. +1090 */ +1091publicstaticfinal String DISABLE_ASSEMBLY = "disableAssembly"; +1092/** +1093 * Disables the Nuspec Analyzer. +1094 */ +1095publicstaticfinal String DISABLE_NUSPEC = "disableNuspec"; +1096/** +1097 * Disables the Central Analyzer. +1098 */ +1099publicstaticfinal String DISABLE_CENTRAL = "disableCentral"; +1100/** +1101 * Disables the Nexus Analyzer. +1102 */ +1103publicstaticfinal String DISABLE_NEXUS = "disableNexus"; +1104/** +1105 * Disables the OpenSSL Analyzer. +1106 */ +1107publicstaticfinal String DISABLE_OPENSSL = "disableOpenSSL"; +1108/** +1109 * The URL of the nexus server. +1110 */ +1111publicstaticfinal String NEXUS_URL = "nexus"; +1112/** +1113 * Whether or not the defined proxy should be used when connecting to Nexus. +1114 */ +1115publicstaticfinal String NEXUS_USES_PROXY = "nexusUsesProxy"; +1116/** +1117 * The CLI argument name for setting the connection string. +1118 */ +1119publicstaticfinal String CONNECTION_STRING = "connectionString"; +1120/** +1121 * The CLI argument name for setting the database user name. +1122 */ +1123publicstaticfinal String DB_NAME = "dbUser"; +1124/** +1125 * The CLI argument name for setting the database password. +1126 */ +1127publicstaticfinal String DB_PASSWORD = "dbPassword"; +1128/** +1129 * The CLI argument name for setting the database driver name. +1130 */ +1131publicstaticfinal String DB_DRIVER = "dbDriverName"; +1132/** +1133 * The CLI argument name for setting the path to the database driver; in case it is not on the class path. +1134 */ +1135publicstaticfinal String DB_DRIVER_PATH = "dbDriverPath"; +1136/** +1137 * The CLI argument name for setting the path to mono for .NET Assembly analysis on non-windows systems. +1138 */ +1139publicstaticfinal String PATH_TO_MONO = "mono"; +1140/** +1141 * The CLI argument name for setting extra extensions. +1142 */ +1143publicstaticfinal String ADDITIONAL_ZIP_EXTENSIONS = "zipExtensions"; +1144/** +1145 * Exclude path argument. +1146 */ +1147publicstaticfinal String EXCLUDE = "exclude"; +1148 } +1149 }
    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 eb5632fa5..aa8c2df17 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.2.11 Reference Package org.owasp.dependencycheck + Dependency-Check Command Line 1.3.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 f49fba682..0a0f41b78 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.2.11 Reference Package org.owasp.dependencycheck + Dependency-Check Command Line 1.3.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 a6fc86ed1..fb39eca17 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.2.11 Reference + Dependency-Check Command Line 1.3.0 Reference diff --git a/dependency-check-cli/xref/overview-summary.html b/dependency-check-cli/xref/overview-summary.html index fece9d527..0c575d8cf 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.2.11 Reference + Dependency-Check Command Line 1.3.0 Reference @@ -24,7 +24,7 @@ -

    Dependency-Check Command Line 1.2.11 Reference

    +

    Dependency-Check Command Line 1.3.0 Reference

    diff --git a/dependency-check-core/apidocs/allclasses-frame.html b/dependency-check-core/apidocs/allclasses-frame.html index 94b74a108..29024d026 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.2.11 API) - +All Classes (Dependency-Check Core 1.3.0 API) + @@ -24,14 +24,20 @@
  • ArchiveAnalyzer
  • ArchiveExtractionException
  • AssemblyAnalyzer
  • +
  • AutoconfAnalyzer
  • +
  • BaseUpdater
  • CachedWebDataSource
  • CentralAnalyzer
  • CentralSearch
  • +
  • CMakeAnalyzer
  • Confidence
  • ConnectionFactory
  • +
  • Cpe
  • CPEAnalyzer
  • +
  • CPEHandler
  • CpeMemoryIndex
  • CpeSuppressionAnalyzer
  • +
  • CpeUpdater
  • CveDB
  • CweDB
  • CweHandler
  • @@ -45,7 +51,7 @@
  • DependencySimilarity
  • DependencyVersion
  • DependencyVersionUtil
  • -
  • DownloadTask
  • +
  • DownloadTask
  • DriverLoader
  • DriverLoadException
  • Engine
  • @@ -57,6 +63,7 @@
  • FalsePositiveAnalyzer
  • FieldAnalyzer
  • Fields
  • +
  • FileFilterBuilder
  • FileNameAnalyzer
  • FileTypeAnalyzer
  • Filter
  • @@ -67,7 +74,6 @@
  • InvalidDataException
  • JarAnalyzer
  • JarAnalyzer.ClassNameInformation
  • -
  • JavaScriptAnalyzer
  • License
  • LuceneUtils
  • MavenArtifact
  • @@ -80,19 +86,20 @@
  • NuspecAnalyzer
  • NuspecParseException
  • NuspecParser
  • -
  • NvdCve12Handler
  • -
  • NvdCve12Handler.Element
  • -
  • NvdCve20Handler
  • -
  • NvdCve20Handler.Element
  • +
  • NvdCve12Handler
  • +
  • NvdCve12Handler.Element
  • +
  • NvdCve20Handler
  • +
  • NvdCve20Handler.Element
  • NvdCveAnalyzer
  • -
  • NvdCveInfo
  • +
  • NvdCveInfo
  • NvdCveUpdater
  • +
  • OpenSSLAnalyzer
  • Pair
  • PomHandler
  • PomParseException
  • PomParser
  • PomUtils
  • -
  • ProcessTask
  • +
  • ProcessTask
  • PropertyType
  • PythonDistributionAnalyzer
  • PythonPackageAnalyzer
  • @@ -101,14 +108,13 @@
  • ReportGenerator.Format
  • ScanAgentException
  • SearchFieldAnalyzer
  • -
  • StandardUpdate
  • SuppressionErrorHandler
  • SuppressionHandler
  • SuppressionParseException
  • SuppressionParser
  • SuppressionRule
  • TokenPairConcatenatingFilter
  • -
  • UpdateableNvdCve
  • +
  • UpdateableNvdCve
  • UpdateException
  • UpdateService
  • UrlStringUtils
  • diff --git a/dependency-check-core/apidocs/allclasses-noframe.html b/dependency-check-core/apidocs/allclasses-noframe.html index ab7e9a2b0..bad68e5d6 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.2.11 API) - +All Classes (Dependency-Check Core 1.3.0 API) + @@ -24,14 +24,20 @@
  • ArchiveAnalyzer
  • ArchiveExtractionException
  • AssemblyAnalyzer
  • +
  • AutoconfAnalyzer
  • +
  • BaseUpdater
  • CachedWebDataSource
  • CentralAnalyzer
  • CentralSearch
  • +
  • CMakeAnalyzer
  • Confidence
  • ConnectionFactory
  • +
  • Cpe
  • CPEAnalyzer
  • +
  • CPEHandler
  • CpeMemoryIndex
  • CpeSuppressionAnalyzer
  • +
  • CpeUpdater
  • CveDB
  • CweDB
  • CweHandler
  • @@ -45,7 +51,7 @@
  • DependencySimilarity
  • DependencyVersion
  • DependencyVersionUtil
  • -
  • DownloadTask
  • +
  • DownloadTask
  • DriverLoader
  • DriverLoadException
  • Engine
  • @@ -57,6 +63,7 @@
  • FalsePositiveAnalyzer
  • FieldAnalyzer
  • Fields
  • +
  • FileFilterBuilder
  • FileNameAnalyzer
  • FileTypeAnalyzer
  • Filter
  • @@ -67,7 +74,6 @@
  • InvalidDataException
  • JarAnalyzer
  • JarAnalyzer.ClassNameInformation
  • -
  • JavaScriptAnalyzer
  • License
  • LuceneUtils
  • MavenArtifact
  • @@ -80,19 +86,20 @@
  • NuspecAnalyzer
  • NuspecParseException
  • NuspecParser
  • -
  • NvdCve12Handler
  • -
  • NvdCve12Handler.Element
  • -
  • NvdCve20Handler
  • -
  • NvdCve20Handler.Element
  • +
  • NvdCve12Handler
  • +
  • NvdCve12Handler.Element
  • +
  • NvdCve20Handler
  • +
  • NvdCve20Handler.Element
  • NvdCveAnalyzer
  • -
  • NvdCveInfo
  • +
  • NvdCveInfo
  • NvdCveUpdater
  • +
  • OpenSSLAnalyzer
  • Pair
  • PomHandler
  • PomParseException
  • PomParser
  • PomUtils
  • -
  • ProcessTask
  • +
  • ProcessTask
  • PropertyType
  • PythonDistributionAnalyzer
  • PythonPackageAnalyzer
  • @@ -101,14 +108,13 @@
  • ReportGenerator.Format
  • ScanAgentException
  • SearchFieldAnalyzer
  • -
  • StandardUpdate
  • SuppressionErrorHandler
  • SuppressionHandler
  • SuppressionParseException
  • SuppressionParser
  • SuppressionRule
  • TokenPairConcatenatingFilter
  • -
  • UpdateableNvdCve
  • +
  • UpdateableNvdCve
  • UpdateException
  • UpdateService
  • UrlStringUtils
  • diff --git a/dependency-check-core/apidocs/constant-values.html b/dependency-check-core/apidocs/constant-values.html index ba5f58a99..c35f1884b 100644 --- a/dependency-check-core/apidocs/constant-values.html +++ b/dependency-check-core/apidocs/constant-values.html @@ -2,16 +2,16 @@ - + -Constant Field Values (Dependency-Check Core 1.2.11 API) - +Constant Field Values (Dependency-Check Core 1.3.0 API) + @@ -166,6 +166,13 @@ + + + + +
    DB_STRUCTURE_RESOURCE "data/initialize.sql"
    + +public static final StringDB_STRUCTURE_UPDATE_RESOURCE"data/upgrade_%s.sql"
  • @@ -179,26 +186,40 @@ + + +public static final String +LAST_CPE_UPDATE +"LAST_CPE_UPDATE" + + public static final String LAST_UPDATED "NVD CVE Modified" - + public static final String LAST_UPDATED_BASE "NVD CVE " - + public static final String MODIFIED "Modified" + + + +public static final String +VERSION +"version" + @@ -234,7 +255,7 @@ + - + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/agent/DependencyCheckScanAgent.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/agent/DependencyCheckScanAgent.html index 60808337f..5febd6c19 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/agent/DependencyCheckScanAgent.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/agent/DependencyCheckScanAgent.html @@ -2,16 +2,16 @@ - + -DependencyCheckScanAgent (Dependency-Check Core 1.2.11 API) - +DependencyCheckScanAgent (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/agent/class-use/DependencyCheckScanAgent.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/agent/class-use/DependencyCheckScanAgent.html index 4a064c5cc..8c20bc6df 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/agent/class-use/DependencyCheckScanAgent.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/agent/class-use/DependencyCheckScanAgent.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.agent.DependencyCheckScanAgent (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.agent.DependencyCheckScanAgent (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/agent/package-frame.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/agent/package-frame.html index a024db62c..fd27b1631 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/agent/package-frame.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/agent/package-frame.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.agent (Dependency-Check Core 1.2.11 API) - +org.owasp.dependencycheck.agent (Dependency-Check Core 1.3.0 API) + 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 d7e9d6c9f..b74cabb3e 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,16 +2,16 @@ - + -org.owasp.dependencycheck.agent (Dependency-Check Core 1.2.11 API) - +org.owasp.dependencycheck.agent (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/agent/package-tree.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/agent/package-tree.html index a65999e9a..9e6458e6a 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/agent/package-tree.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/agent/package-tree.html @@ -2,16 +2,16 @@ - + -org.owasp.dependencycheck.agent Class Hierarchy (Dependency-Check Core 1.2.11 API) - +org.owasp.dependencycheck.agent Class Hierarchy (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/agent/package-use.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/agent/package-use.html index 911c06088..b860a7172 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/agent/package-use.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/agent/package-use.html @@ -2,16 +2,16 @@ - + -Uses of Package org.owasp.dependencycheck.agent (Dependency-Check Core 1.2.11 API) - +Uses of Package org.owasp.dependencycheck.agent (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/AbstractAnalyzer.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/AbstractAnalyzer.html index 3882d1259..b0394d9e4 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/AbstractAnalyzer.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/AbstractAnalyzer.html @@ -2,16 +2,16 @@ - + -AbstractAnalyzer (Dependency-Check Core 1.2.11 API) - +AbstractAnalyzer (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/AbstractFileTypeAnalyzer.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/AbstractFileTypeAnalyzer.html index 0266f556b..f69609a24 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/AbstractFileTypeAnalyzer.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/AbstractFileTypeAnalyzer.html @@ -2,16 +2,16 @@ - + -AbstractFileTypeAnalyzer (Dependency-Check Core 1.2.11 API) - +AbstractFileTypeAnalyzer (Dependency-Check Core 1.3.0 API) + @@ -102,11 +102,11 @@
  • All Implemented Interfaces:
    -
    Analyzer, FileTypeAnalyzer
    +
    FileFilter, Analyzer, FileTypeAnalyzer
    Direct Known Subclasses:
    -
    ArchiveAnalyzer, AssemblyAnalyzer, CentralAnalyzer, JarAnalyzer, JavaScriptAnalyzer, NexusAnalyzer, NuspecAnalyzer, PythonDistributionAnalyzer, PythonPackageAnalyzer
    +
    ArchiveAnalyzer, AssemblyAnalyzer, AutoconfAnalyzer, CentralAnalyzer, CMakeAnalyzer, JarAnalyzer, NexusAnalyzer, NuspecAnalyzer, OpenSSLAnalyzer, PythonDistributionAnalyzer, PythonPackageAnalyzer


    @@ -154,88 +154,86 @@ implements Method and Description +boolean +accept(File pathname)  + + void analyze(Dependency dependency, Engine engine)
    Analyzes a given dependency.
    - + protected abstract void analyzeFileType(Dependency dependency, Engine engine)
    Analyzes a given dependency.
    - + protected abstract String getAnalyzerEnabledSettingKey()
    Returns the setting key to determine if the analyzer is enabled.
    - -protected abstract Set<String> -getSupportedExtensions() + +protected abstract FileFilter +getFileFilter()
    - Returns a list of supported file extensions.
    + Returns the FileFilter used to determine which files are to be analyzed. - + void initialize()
    Initializes the analyzer.
    - + protected abstract void initializeFileTypeAnalyzer()
    Initializes the file type analyzer.
    - + boolean isEnabled()
    Get the value of enabled.
    - + protected boolean isFilesMatched()
    Get the value of filesMatched.
    - + protected static Set<String> newHashSet(String... strings)
    Utility method to help in the creation of the extensions set.
    - + void reset()
    Resets the enabled flag on the analyzer.
    - + void setEnabled(boolean enabled)
    Set the value of enabled.
    - + protected void setFilesMatched(boolean filesMatched)
    Set the value of filesMatched.
    - -boolean -supportsExtension(String extension) -
    Returns whether or not this analyzer can process the given extension.
    - -
  • @@ -335,24 +332,21 @@ implements Parameters:
    enabled - new value of enabled
    -
    + @@ -377,8 +371,8 @@ implements Dependency dependency, Engine engine) throws AnalysisException -
    Analyzes a given dependency. If the dependency is an archive, such as a WAR or EAR, the contents are extracted, - scanned, and added to the list of dependencies within the engine.
    +
    Analyzes a given dependency. If the dependency is an archive, such as a WAR or EAR, the contents are extracted, scanned, + and added to the list of dependencies within the engine.
    Parameters:
    dependency - the dependency to analyze
    engine - the engine scanning
    Throws:
    AnalysisException - thrown if there is an analysis exception
    @@ -437,8 +431,8 @@ implements Dependency dependency, Engine engine) throws AnalysisException -
    Analyzes a given dependency. If the dependency is an archive, such as a WAR or EAR, the contents are extracted, - scanned, and added to the list of dependencies within the engine.
    +
    Analyzes a given dependency. If the dependency is an archive, such as a WAR or EAR, the contents are extracted, scanned, + and added to the list of dependencies within the engine.
    Specified by:
    analyze in interface Analyzer
    @@ -447,19 +441,17 @@ implements AnalysisException - thrown if there is an analysis exception
    - + @@ -470,9 +462,9 @@ implements Set<String> newHashSet(String... strings)

    - Utility method to help in the creation of the extensions set. This constructs a new Set that can be used in a - final static declaration.

    - + Utility method to help in the creation of the extensions set. This constructs a new Set that can be used in a final static + declaration.

    +

    This implementation was copied from http://stackoverflow.com/questions/2041778/initialize-java-hashset-values-by-construction

    diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzer.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzer.html index 223a39cf9..88e362adf 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzer.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzer.html @@ -2,16 +2,16 @@ - + -AbstractSuppressionAnalyzer (Dependency-Check Core 1.2.11 API) - +AbstractSuppressionAnalyzer (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/AnalysisPhase.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/AnalysisPhase.html index 7fcc3a48c..87fb5484f 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/AnalysisPhase.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/AnalysisPhase.html @@ -2,16 +2,16 @@ - + -AnalysisPhase (Dependency-Check Core 1.2.11 API) - +AnalysisPhase (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/Analyzer.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/Analyzer.html index 6b268b359..77ef88162 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/Analyzer.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/Analyzer.html @@ -2,16 +2,16 @@ - + -Analyzer (Dependency-Check Core 1.2.11 API) - +Analyzer (Dependency-Check Core 1.3.0 API) + @@ -93,7 +93,7 @@
    All Known Implementing Classes:
    -
    AbstractAnalyzer, AbstractFileTypeAnalyzer, AbstractSuppressionAnalyzer, ArchiveAnalyzer, AssemblyAnalyzer, CentralAnalyzer, CPEAnalyzer, CpeSuppressionAnalyzer, DependencyBundlingAnalyzer, FalsePositiveAnalyzer, FileNameAnalyzer, HintAnalyzer, JarAnalyzer, JavaScriptAnalyzer, NexusAnalyzer, NuspecAnalyzer, NvdCveAnalyzer, PythonDistributionAnalyzer, PythonPackageAnalyzer, VulnerabilitySuppressionAnalyzer
    +
    AbstractAnalyzer, AbstractFileTypeAnalyzer, AbstractSuppressionAnalyzer, ArchiveAnalyzer, AssemblyAnalyzer, AutoconfAnalyzer, CentralAnalyzer, CMakeAnalyzer, CPEAnalyzer, CpeSuppressionAnalyzer, DependencyBundlingAnalyzer, FalsePositiveAnalyzer, FileNameAnalyzer, HintAnalyzer, JarAnalyzer, NexusAnalyzer, NuspecAnalyzer, NvdCveAnalyzer, OpenSSLAnalyzer, PythonDistributionAnalyzer, PythonPackageAnalyzer, VulnerabilitySuppressionAnalyzer


    diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/AnalyzerService.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/AnalyzerService.html index a4aaef9f6..e6b299338 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/AnalyzerService.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/AnalyzerService.html @@ -2,16 +2,16 @@ - + -AnalyzerService (Dependency-Check Core 1.2.11 API) - +AnalyzerService (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/ArchiveAnalyzer.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/ArchiveAnalyzer.html index 91c594afc..f546080cd 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/ArchiveAnalyzer.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/ArchiveAnalyzer.html @@ -2,16 +2,16 @@ - + -ArchiveAnalyzer (Dependency-Check Core 1.2.11 API) - +ArchiveAnalyzer (Dependency-Check Core 1.3.0 API) + @@ -107,15 +107,15 @@
  • All Implemented Interfaces:
    -
    Analyzer, FileTypeAnalyzer
    +
    FileFilter, Analyzer, FileTypeAnalyzer


    public class ArchiveAnalyzer
     extends AbstractFileTypeAnalyzer

    - An analyzer that extracts files from archives and ensures any supported files contained within the archive are added - to the dependency list.

    + An analyzer that extracts files from archives and ensures any supported files contained within the archive are added to the + dependency list.

    Author:
    Jeremy Long
  • @@ -179,15 +179,16 @@ extends -String -getName() -
    Returns the name of the analyzer.
    +protected FileFilter +getFileFilter() +
    + Returns the FileFilter used to determine which files are to be analyzed.
    -Set<String> -getSupportedExtensions() -
    Returns a list of file EXTENSIONS supported by this analyzer.
    +String +getName() +
    Returns the name of the analyzer.
    @@ -202,7 +203,7 @@ extends AbstractFileTypeAnalyzer -analyze, initialize, isEnabled, isFilesMatched, newHashSet, reset, setEnabled, setFilesMatched, supportsExtension +accept, analyze, initialize, isEnabled, isFilesMatched, newHashSet, reset, setEnabled, setFilesMatched - + @@ -370,7 +377,7 @@ extends @@ -154,18 +155,6 @@ extends

    Method Detail

    - - - - diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/HintAnalyzer.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/HintAnalyzer.html index 5bf615f56..9aa81dd1b 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/HintAnalyzer.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/HintAnalyzer.html @@ -2,16 +2,16 @@ - + -HintAnalyzer (Dependency-Check Core 1.2.11 API) - +HintAnalyzer (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/JarAnalyzer.ClassNameInformation.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/JarAnalyzer.ClassNameInformation.html index 8b03df8a4..87f5b3333 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/JarAnalyzer.ClassNameInformation.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/JarAnalyzer.ClassNameInformation.html @@ -2,16 +2,16 @@ - + -JarAnalyzer.ClassNameInformation (Dependency-Check Core 1.2.11 API) - +JarAnalyzer.ClassNameInformation (Dependency-Check Core 1.3.0 API) + @@ -38,7 +38,7 @@ @@ -114,11 +114,24 @@ class  +AutoconfAnalyzer +
    Used to analyze Autoconf input files named configure.ac or configure.in.
    + + + +class  CentralAnalyzer
    Analyzer which will attempt to locate a dependency, and the GAV information, by querying Central for the dependency's SHA-1 digest.
    + +class  +CMakeAnalyzer +
    + Used to analyze CMake build files, and collect information that can be used to determine the associated CPE.
    + + class  JarAnalyzer @@ -127,22 +140,22 @@ class  -JavaScriptAnalyzer -
    Used to analyze a JavaScript file to gather information to aid in identification of a CPE identifier.
    - - - -class  NexusAnalyzer
    Analyzer which will attempt to locate a dependency on a Nexus service by SHA-1 digest of the dependency.
    - + class  NuspecAnalyzer
    Analyzer which will parse a Nuspec file to gather module information.
    + +class  +OpenSSLAnalyzer +
    Used to analyze OpenSSL source code present in the file system.
    + + class  PythonDistributionAnalyzer diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/AbstractSuppressionAnalyzer.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/AbstractSuppressionAnalyzer.html index d89824a24..d5d52c84d 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/AbstractSuppressionAnalyzer.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/AbstractSuppressionAnalyzer.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.analyzer.AbstractSuppressionAnalyzer (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.analyzer.AbstractSuppressionAnalyzer (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/AnalysisPhase.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/AnalysisPhase.html index 2cc7cf5a7..266420157 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/AnalysisPhase.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/AnalysisPhase.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.analyzer.AnalysisPhase (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.analyzer.AnalysisPhase (Dependency-Check Core 1.3.0 API) + @@ -144,28 +144,28 @@ AnalysisPhase +OpenSSLAnalyzer.getAnalysisPhase() +
    Tell that we are used for information collection.
    + + + +AnalysisPhase NvdCveAnalyzer.getAnalysisPhase()
    Returns the analysis phase that this analyzer should run in.
    - + AnalysisPhase NuspecAnalyzer.getAnalysisPhase()
    Returns the analysis phase under which the analyzer runs.
    - + AnalysisPhase NexusAnalyzer.getAnalysisPhase()
    Returns the analysis phase under which the analyzer runs.
    - -AnalysisPhase -JavaScriptAnalyzer.getAnalysisPhase() -
    Returns the phase that the analyzer is intended to run in.
    - - AnalysisPhase JarAnalyzer.getAnalysisPhase() @@ -210,10 +210,22 @@ AnalysisPhase +CMakeAnalyzer.getAnalysisPhase() +
    Tell that we are used for information collection.
    + + + +AnalysisPhase CentralAnalyzer.getAnalysisPhase()
    Returns the analysis phase under which the analyzer runs.
    + +AnalysisPhase +AutoconfAnalyzer.getAnalysisPhase() +
    Returns the phase that the analyzer is intended to run in.
    + + AnalysisPhase AssemblyAnalyzer.getAnalysisPhase() diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/Analyzer.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/Analyzer.html index 76765b490..4c2459464 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/Analyzer.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/Analyzer.html @@ -2,16 +2,16 @@ - + -Uses of Interface org.owasp.dependencycheck.analyzer.Analyzer (Dependency-Check Core 1.2.11 API) - +Uses of Interface org.owasp.dependencycheck.analyzer.Analyzer (Dependency-Check Core 1.3.0 API) + @@ -207,8 +207,8 @@ class  ArchiveAnalyzer
    - An analyzer that extracts files from archives and ensures any supported files contained within the archive are added - to the dependency list.
    + An analyzer that extracts files from archives and ensures any supported files contained within the archive are added to the + dependency list. @@ -219,11 +219,24 @@ class  +AutoconfAnalyzer +
    Used to analyze Autoconf input files named configure.ac or configure.in.
    + + + +class  CentralAnalyzer
    Analyzer which will attempt to locate a dependency, and the GAV information, by querying Central for the dependency's SHA-1 digest.
    + +class  +CMakeAnalyzer +
    + Used to analyze CMake build files, and collect information that can be used to determine the associated CPE.
    + + class  CPEAnalyzer @@ -267,29 +280,29 @@ class  -JavaScriptAnalyzer -
    Used to analyze a JavaScript file to gather information to aid in identification of a CPE identifier.
    - - - -class  NexusAnalyzer
    Analyzer which will attempt to locate a dependency on a Nexus service by SHA-1 digest of the dependency.
    - + class  NuspecAnalyzer
    Analyzer which will parse a Nuspec file to gather module information.
    - + class  NvdCveAnalyzer
    NvdCveAnalyzer is a utility class that takes a project dependency and attempts to discern if there is an associated CVEs.
    + +class  +OpenSSLAnalyzer +
    Used to analyze OpenSSL source code present in the file system.
    + + class  PythonDistributionAnalyzer diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/AnalyzerService.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/AnalyzerService.html index 456b0214f..1ca96d707 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/AnalyzerService.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/AnalyzerService.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.analyzer.AnalyzerService (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.analyzer.AnalyzerService (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/ArchiveAnalyzer.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/ArchiveAnalyzer.html index 2abfded03..02d5a7ebd 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/ArchiveAnalyzer.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/ArchiveAnalyzer.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.analyzer.ArchiveAnalyzer (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.analyzer.ArchiveAnalyzer (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/AssemblyAnalyzer.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/AssemblyAnalyzer.html index 839b5c94e..9353863d8 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/AssemblyAnalyzer.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/AssemblyAnalyzer.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.analyzer.AssemblyAnalyzer (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.analyzer.AssemblyAnalyzer (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/AutoconfAnalyzer.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/AutoconfAnalyzer.html new file mode 100644 index 000000000..462a17d7c --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/AutoconfAnalyzer.html @@ -0,0 +1,117 @@ + + + + + + +Uses of Class org.owasp.dependencycheck.analyzer.AutoconfAnalyzer (Dependency-Check Core 1.3.0 API) + + + + + + + +
    + + + + + +
    + + +
    +

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

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

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

    + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/CMakeAnalyzer.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/CMakeAnalyzer.html new file mode 100644 index 000000000..61840f6a9 --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/CMakeAnalyzer.html @@ -0,0 +1,117 @@ + + + + + + +Uses of Class org.owasp.dependencycheck.analyzer.CMakeAnalyzer (Dependency-Check Core 1.3.0 API) + + + + + + + +
    + + + + + +
    + + +
    +

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

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

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

    + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/CPEAnalyzer.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/CPEAnalyzer.html index 3b614d926..d1734f4cf 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/CPEAnalyzer.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/CPEAnalyzer.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.analyzer.CPEAnalyzer (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.analyzer.CPEAnalyzer (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/CentralAnalyzer.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/CentralAnalyzer.html index 7d5f74eaf..56e515908 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/CentralAnalyzer.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/CentralAnalyzer.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.analyzer.CentralAnalyzer (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.analyzer.CentralAnalyzer (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/CpeSuppressionAnalyzer.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/CpeSuppressionAnalyzer.html index f29efe855..80daacd6f 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/CpeSuppressionAnalyzer.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/CpeSuppressionAnalyzer.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.analyzer.CpeSuppressionAnalyzer (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.analyzer.CpeSuppressionAnalyzer (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/DependencyBundlingAnalyzer.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/DependencyBundlingAnalyzer.html index 2944a850d..99adb8c62 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/DependencyBundlingAnalyzer.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/DependencyBundlingAnalyzer.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.analyzer.DependencyBundlingAnalyzer (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.analyzer.DependencyBundlingAnalyzer (Dependency-Check Core 1.3.0 API) + 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 2160c6058..0f1988999 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,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.analyzer.FalsePositiveAnalyzer (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.analyzer.FalsePositiveAnalyzer (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/FileNameAnalyzer.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/FileNameAnalyzer.html index bb9699a35..f2f64b197 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/FileNameAnalyzer.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/FileNameAnalyzer.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.analyzer.FileNameAnalyzer (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.analyzer.FileNameAnalyzer (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/FileTypeAnalyzer.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/FileTypeAnalyzer.html index d02a66ba7..76752197f 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/FileTypeAnalyzer.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/FileTypeAnalyzer.html @@ -2,16 +2,16 @@ - + -Uses of Interface org.owasp.dependencycheck.analyzer.FileTypeAnalyzer (Dependency-Check Core 1.2.11 API) - +Uses of Interface org.owasp.dependencycheck.analyzer.FileTypeAnalyzer (Dependency-Check Core 1.3.0 API) + @@ -134,8 +134,8 @@ class  ArchiveAnalyzer
    - An analyzer that extracts files from archives and ensures any supported files contained within the archive are added - to the dependency list.
    + An analyzer that extracts files from archives and ensures any supported files contained within the archive are added to the + dependency list. @@ -146,11 +146,24 @@ class  +AutoconfAnalyzer +
    Used to analyze Autoconf input files named configure.ac or configure.in.
    + + + +class  CentralAnalyzer
    Analyzer which will attempt to locate a dependency, and the GAV information, by querying Central for the dependency's SHA-1 digest.
    + +class  +CMakeAnalyzer +
    + Used to analyze CMake build files, and collect information that can be used to determine the associated CPE.
    + + class  JarAnalyzer @@ -159,22 +172,22 @@ class  -JavaScriptAnalyzer -
    Used to analyze a JavaScript file to gather information to aid in identification of a CPE identifier.
    - - - -class  NexusAnalyzer
    Analyzer which will attempt to locate a dependency on a Nexus service by SHA-1 digest of the dependency.
    - + class  NuspecAnalyzer
    Analyzer which will parse a Nuspec file to gather module information.
    + +class  +OpenSSLAnalyzer +
    Used to analyze OpenSSL source code present in the file system.
    + + class  PythonDistributionAnalyzer diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/HintAnalyzer.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/HintAnalyzer.html index 42322f0c1..d6692432c 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/HintAnalyzer.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/HintAnalyzer.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.analyzer.HintAnalyzer (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.analyzer.HintAnalyzer (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/JarAnalyzer.ClassNameInformation.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/JarAnalyzer.ClassNameInformation.html index 0eda1601c..d56fa43d9 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/JarAnalyzer.ClassNameInformation.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/JarAnalyzer.ClassNameInformation.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.analyzer.JarAnalyzer.ClassNameInformation (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.analyzer.JarAnalyzer.ClassNameInformation (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/JarAnalyzer.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/JarAnalyzer.html index a15bb8efd..e7ce5b2d1 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/JarAnalyzer.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/JarAnalyzer.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.analyzer.JarAnalyzer (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.analyzer.JarAnalyzer (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/NexusAnalyzer.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/NexusAnalyzer.html index fb899ad48..a1bd8e56c 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/NexusAnalyzer.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/NexusAnalyzer.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.analyzer.NexusAnalyzer (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.analyzer.NexusAnalyzer (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/NuspecAnalyzer.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/NuspecAnalyzer.html index f0cc01d9e..9df704e55 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/NuspecAnalyzer.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/NuspecAnalyzer.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.analyzer.NuspecAnalyzer (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.analyzer.NuspecAnalyzer (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/NvdCveAnalyzer.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/NvdCveAnalyzer.html index 420ee3786..7ec2ebc79 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/NvdCveAnalyzer.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/NvdCveAnalyzer.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.analyzer.NvdCveAnalyzer (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.analyzer.NvdCveAnalyzer (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/OpenSSLAnalyzer.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/OpenSSLAnalyzer.html new file mode 100644 index 000000000..30119253f --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/OpenSSLAnalyzer.html @@ -0,0 +1,117 @@ + + + + + + +Uses of Class org.owasp.dependencycheck.analyzer.OpenSSLAnalyzer (Dependency-Check Core 1.3.0 API) + + + + + + + +
    + + + + + +
    + + +
    +

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

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

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

    + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/PythonDistributionAnalyzer.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/PythonDistributionAnalyzer.html index b5fe7a5e1..1c20622bc 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/PythonDistributionAnalyzer.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/PythonDistributionAnalyzer.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.analyzer.PythonDistributionAnalyzer (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.analyzer.PythonDistributionAnalyzer (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/PythonPackageAnalyzer.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/PythonPackageAnalyzer.html index 4f4286a26..c95ab8617 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/PythonPackageAnalyzer.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/PythonPackageAnalyzer.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.analyzer.PythonPackageAnalyzer (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.analyzer.PythonPackageAnalyzer (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/VulnerabilitySuppressionAnalyzer.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/VulnerabilitySuppressionAnalyzer.html index bc6dfa85a..90c5a79e7 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/VulnerabilitySuppressionAnalyzer.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/class-use/VulnerabilitySuppressionAnalyzer.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.analyzer.VulnerabilitySuppressionAnalyzer (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.analyzer.VulnerabilitySuppressionAnalyzer (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/exception/AnalysisException.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/exception/AnalysisException.html index e398c6848..abdf43e73 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/exception/AnalysisException.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/exception/AnalysisException.html @@ -2,16 +2,16 @@ - + -AnalysisException (Dependency-Check Core 1.2.11 API) - +AnalysisException (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/exception/ArchiveExtractionException.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/exception/ArchiveExtractionException.html index f65dff492..c86666521 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/exception/ArchiveExtractionException.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/exception/ArchiveExtractionException.html @@ -2,16 +2,16 @@ - + -ArchiveExtractionException (Dependency-Check Core 1.2.11 API) - +ArchiveExtractionException (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/exception/class-use/AnalysisException.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/exception/class-use/AnalysisException.html index 2016454a7..77ed8e81c 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/exception/class-use/AnalysisException.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/exception/class-use/AnalysisException.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.analyzer.exception.AnalysisException (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.analyzer.exception.AnalysisException (Dependency-Check Core 1.3.0 API) + @@ -184,26 +184,26 @@ Engine engine)  +protected void +OpenSSLAnalyzer.analyzeFileType(Dependency dependency, + Engine engine) +
    Analyzes python packages and adds evidence to the dependency.
    + + + void NuspecAnalyzer.analyzeFileType(Dependency dependency, Engine engine)
    Performs the analysis.
    - + void NexusAnalyzer.analyzeFileType(Dependency dependency, Engine engine)
    Performs the analysis.
    - -void -JavaScriptAnalyzer.analyzeFileType(Dependency dependency, - Engine engine) -
    Loads a specified JavaScript file and collects information from the copyright information contained within.
    - - void JarAnalyzer.analyzeFileType(Dependency dependency, @@ -213,12 +213,24 @@ +protected void +CMakeAnalyzer.analyzeFileType(Dependency dependency, + Engine engine) +
    Analyzes python packages and adds evidence to the dependency.
    + + + void CentralAnalyzer.analyzeFileType(Dependency dependency, Engine engine)
    Performs the analysis.
    + +protected void +AutoconfAnalyzer.analyzeFileType(Dependency dependency, + Engine engine)  + void AssemblyAnalyzer.analyzeFileType(Dependency dependency, diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/exception/class-use/ArchiveExtractionException.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/exception/class-use/ArchiveExtractionException.html index 73957cad7..ef492f9d6 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/exception/class-use/ArchiveExtractionException.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/exception/class-use/ArchiveExtractionException.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.analyzer.exception.ArchiveExtractionException (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.analyzer.exception.ArchiveExtractionException (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/exception/package-frame.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/exception/package-frame.html index 1f8322bda..b470823ca 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/exception/package-frame.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/exception/package-frame.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.analyzer.exception (Dependency-Check Core 1.2.11 API) - +org.owasp.dependencycheck.analyzer.exception (Dependency-Check Core 1.3.0 API) + 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 e2a8cdcfd..fb1ff0c33 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,16 +2,16 @@ - + -org.owasp.dependencycheck.analyzer.exception (Dependency-Check Core 1.2.11 API) - +org.owasp.dependencycheck.analyzer.exception (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/exception/package-tree.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/exception/package-tree.html index e33ad477a..a8720526f 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/exception/package-tree.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/exception/package-tree.html @@ -2,16 +2,16 @@ - + -org.owasp.dependencycheck.analyzer.exception Class Hierarchy (Dependency-Check Core 1.2.11 API) - +org.owasp.dependencycheck.analyzer.exception Class Hierarchy (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/exception/package-use.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/exception/package-use.html index d2a49de9b..5a58b649d 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/exception/package-use.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/exception/package-use.html @@ -2,16 +2,16 @@ - + -Uses of Package org.owasp.dependencycheck.analyzer.exception (Dependency-Check Core 1.2.11 API) - +Uses of Package org.owasp.dependencycheck.analyzer.exception (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/package-frame.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/package-frame.html index aff25b898..ae99e4885 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/package-frame.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/package-frame.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.analyzer (Dependency-Check Core 1.2.11 API) - +org.owasp.dependencycheck.analyzer (Dependency-Check Core 1.3.0 API) + @@ -24,7 +24,9 @@
  • AnalyzerService
  • ArchiveAnalyzer
  • AssemblyAnalyzer
  • +
  • AutoconfAnalyzer
  • CentralAnalyzer
  • +
  • CMakeAnalyzer
  • CPEAnalyzer
  • CpeSuppressionAnalyzer
  • DependencyBundlingAnalyzer
  • @@ -33,10 +35,10 @@
  • HintAnalyzer
  • JarAnalyzer
  • JarAnalyzer.ClassNameInformation
  • -
  • JavaScriptAnalyzer
  • NexusAnalyzer
  • NuspecAnalyzer
  • NvdCveAnalyzer
  • +
  • OpenSSLAnalyzer
  • PythonDistributionAnalyzer
  • PythonPackageAnalyzer
  • VulnerabilitySuppressionAnalyzer
  • 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 4c9348a7d..2af156d2d 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,16 +2,16 @@ - + -org.owasp.dependencycheck.analyzer (Dependency-Check Core 1.2.11 API) - +org.owasp.dependencycheck.analyzer (Dependency-Check Core 1.3.0 API) + @@ -129,8 +129,8 @@ ArchiveAnalyzer
    - An analyzer that extracts files from archives and ensures any supported files contained within the archive are added - to the dependency list.
    + An analyzer that extracts files from archives and ensures any supported files contained within the archive are added to the + dependency list. @@ -140,12 +140,25 @@ +AutoconfAnalyzer + +
    Used to analyze Autoconf input files named configure.ac or configure.in.
    + + + CentralAnalyzer
    Analyzer which will attempt to locate a dependency, and the GAV information, by querying Central for the dependency's SHA-1 digest.
    + +CMakeAnalyzer + +
    + Used to analyze CMake build files, and collect information that can be used to determine the associated CPE.
    + + CPEAnalyzer @@ -194,30 +207,30 @@ -JavaScriptAnalyzer - -
    Used to analyze a JavaScript file to gather information to aid in identification of a CPE identifier.
    - - - NexusAnalyzer
    Analyzer which will attempt to locate a dependency on a Nexus service by SHA-1 digest of the dependency.
    - + NuspecAnalyzer
    Analyzer which will parse a Nuspec file to gather module information.
    - + NvdCveAnalyzer
    NvdCveAnalyzer is a utility class that takes a project dependency and attempts to discern if there is an associated CVEs.
    + +OpenSSLAnalyzer + +
    Used to analyze OpenSSL source code present in the file system.
    + + PythonDistributionAnalyzer diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/package-tree.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/package-tree.html index 5adf1cc3d..88cff5505 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/package-tree.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/package-tree.html @@ -2,16 +2,16 @@ - + -org.owasp.dependencycheck.analyzer Class Hierarchy (Dependency-Check Core 1.2.11 API) - +org.owasp.dependencycheck.analyzer Class Hierarchy (Dependency-Check Core 1.3.0 API) + @@ -81,11 +81,13 @@ @@ -113,7 +115,12 @@ diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/package-use.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/package-use.html index d8f5ad230..cfd61c0c5 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/package-use.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/analyzer/package-use.html @@ -2,16 +2,16 @@ - + -Uses of Package org.owasp.dependencycheck.analyzer (Dependency-Check Core 1.2.11 API) - +Uses of Package org.owasp.dependencycheck.analyzer (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/class-use/Engine.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/class-use/Engine.html index 68cd99bab..52c5d9e81 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/class-use/Engine.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/class-use/Engine.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.Engine (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.Engine (Dependency-Check Core 1.3.0 API) + @@ -211,26 +211,26 @@ Engine engine)
      +protected void +OpenSSLAnalyzer.analyzeFileType(Dependency dependency, + Engine engine) +
    Analyzes python packages and adds evidence to the dependency.
    + + + void NuspecAnalyzer.analyzeFileType(Dependency dependency, Engine engine)
    Performs the analysis.
    - + void NexusAnalyzer.analyzeFileType(Dependency dependency, Engine engine)
    Performs the analysis.
    - -void -JavaScriptAnalyzer.analyzeFileType(Dependency dependency, - Engine engine) -
    Loads a specified JavaScript file and collects information from the copyright information contained within.
    - - void JarAnalyzer.analyzeFileType(Dependency dependency, @@ -240,12 +240,24 @@ +protected void +CMakeAnalyzer.analyzeFileType(Dependency dependency, + Engine engine) +
    Analyzes python packages and adds evidence to the dependency.
    + + + void CentralAnalyzer.analyzeFileType(Dependency dependency, Engine engine)
    Performs the analysis.
    + +protected void +AutoconfAnalyzer.analyzeFileType(Dependency dependency, + Engine engine)  + void AssemblyAnalyzer.analyzeFileType(Dependency dependency, diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/central/CentralSearch.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/central/CentralSearch.html index d250789ad..45628afff 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/central/CentralSearch.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/central/CentralSearch.html @@ -2,16 +2,16 @@ - + -CentralSearch (Dependency-Check Core 1.2.11 API) - +CentralSearch (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/central/class-use/CentralSearch.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/central/class-use/CentralSearch.html index cc377b610..f3bda647d 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/central/class-use/CentralSearch.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/central/class-use/CentralSearch.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.data.central.CentralSearch (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.data.central.CentralSearch (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/central/package-frame.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/central/package-frame.html index 805a823ac..a399d68a1 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/central/package-frame.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/central/package-frame.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.data.central (Dependency-Check Core 1.2.11 API) - +org.owasp.dependencycheck.data.central (Dependency-Check Core 1.3.0 API) + 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 f19966e05..92f4ed197 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,16 +2,16 @@ - + -org.owasp.dependencycheck.data.central (Dependency-Check Core 1.2.11 API) - +org.owasp.dependencycheck.data.central (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/central/package-tree.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/central/package-tree.html index 11cb2442b..93ae7a416 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/central/package-tree.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/central/package-tree.html @@ -2,16 +2,16 @@ - + -org.owasp.dependencycheck.data.central Class Hierarchy (Dependency-Check Core 1.2.11 API) - +org.owasp.dependencycheck.data.central Class Hierarchy (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/central/package-use.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/central/package-use.html index b1720deb9..0c0970fd1 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/central/package-use.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/central/package-use.html @@ -2,16 +2,16 @@ - + -Uses of Package org.owasp.dependencycheck.data.central (Dependency-Check Core 1.2.11 API) - +Uses of Package org.owasp.dependencycheck.data.central (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/CpeMemoryIndex.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/CpeMemoryIndex.html index 0ad7a3338..3b4a271da 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/CpeMemoryIndex.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/CpeMemoryIndex.html @@ -2,16 +2,16 @@ - + -CpeMemoryIndex (Dependency-Check Core 1.2.11 API) - +CpeMemoryIndex (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/Fields.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/Fields.html index ebd087359..3aef33aa8 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/Fields.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/Fields.html @@ -2,16 +2,16 @@ - + -Fields (Dependency-Check Core 1.2.11 API) - +Fields (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/IndexEntry.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/IndexEntry.html index e5b260506..6863b1bfe 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/IndexEntry.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/IndexEntry.html @@ -2,16 +2,16 @@ - + -IndexEntry (Dependency-Check Core 1.2.11 API) - +IndexEntry (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/IndexException.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/IndexException.html index 3f1cb3abb..5086f0211 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/IndexException.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/IndexException.html @@ -2,16 +2,16 @@ - + -IndexException (Dependency-Check Core 1.2.11 API) - +IndexException (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/class-use/CpeMemoryIndex.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/class-use/CpeMemoryIndex.html index 80f1b1bed..6ab768e03 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/class-use/CpeMemoryIndex.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/class-use/CpeMemoryIndex.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.data.cpe.CpeMemoryIndex (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.data.cpe.CpeMemoryIndex (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/class-use/Fields.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/class-use/Fields.html index 9e3fc64d0..6a8b41b89 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/class-use/Fields.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/class-use/Fields.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.data.cpe.Fields (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.data.cpe.Fields (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/class-use/IndexEntry.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/class-use/IndexEntry.html index 81d77f6a4..7c92bf207 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/class-use/IndexEntry.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/class-use/IndexEntry.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.data.cpe.IndexEntry (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.data.cpe.IndexEntry (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/class-use/IndexException.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/class-use/IndexException.html index 1c417ed3e..234446a8a 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/class-use/IndexException.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/class-use/IndexException.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.data.cpe.IndexException (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.data.cpe.IndexException (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/package-frame.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/package-frame.html index 1d7a40c8a..52ed34d62 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/package-frame.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/package-frame.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.data.cpe (Dependency-Check Core 1.2.11 API) - +org.owasp.dependencycheck.data.cpe (Dependency-Check Core 1.3.0 API) + 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 6c04b4509..2a50aa99e 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,16 +2,16 @@ - + -org.owasp.dependencycheck.data.cpe (Dependency-Check Core 1.2.11 API) - +org.owasp.dependencycheck.data.cpe (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/package-tree.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/package-tree.html index c3086d09f..1dbbc6ad7 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/package-tree.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/package-tree.html @@ -2,16 +2,16 @@ - + -org.owasp.dependencycheck.data.cpe Class Hierarchy (Dependency-Check Core 1.2.11 API) - +org.owasp.dependencycheck.data.cpe Class Hierarchy (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/package-use.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/package-use.html index cbabe50c3..4f29c0b8d 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/package-use.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cpe/package-use.html @@ -2,16 +2,16 @@ - + -Uses of Package org.owasp.dependencycheck.data.cpe (Dependency-Check Core 1.2.11 API) - +Uses of Package org.owasp.dependencycheck.data.cpe (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cwe/CweDB.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cwe/CweDB.html index 9de1abb51..211f9e5e0 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cwe/CweDB.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cwe/CweDB.html @@ -2,16 +2,16 @@ - + -CweDB (Dependency-Check Core 1.2.11 API) - +CweDB (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cwe/CweHandler.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cwe/CweHandler.html index 958ea83fb..ea4c07c5e 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cwe/CweHandler.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cwe/CweHandler.html @@ -2,16 +2,16 @@ - + -CweHandler (Dependency-Check Core 1.2.11 API) - +CweHandler (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cwe/class-use/CweDB.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cwe/class-use/CweDB.html index e3f2549d9..e0aad66c6 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cwe/class-use/CweDB.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cwe/class-use/CweDB.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.data.cwe.CweDB (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.data.cwe.CweDB (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cwe/class-use/CweHandler.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cwe/class-use/CweHandler.html index 79694afe9..dc4429d82 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cwe/class-use/CweHandler.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cwe/class-use/CweHandler.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.data.cwe.CweHandler (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.data.cwe.CweHandler (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cwe/package-frame.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cwe/package-frame.html index fd846a3ec..b77e264dc 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cwe/package-frame.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cwe/package-frame.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.data.cwe (Dependency-Check Core 1.2.11 API) - +org.owasp.dependencycheck.data.cwe (Dependency-Check Core 1.3.0 API) + 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 691701caa..482d52c1e 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,16 +2,16 @@ - + -org.owasp.dependencycheck.data.cwe (Dependency-Check Core 1.2.11 API) - +org.owasp.dependencycheck.data.cwe (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cwe/package-tree.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cwe/package-tree.html index c2f831260..604394451 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cwe/package-tree.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cwe/package-tree.html @@ -2,16 +2,16 @@ - + -org.owasp.dependencycheck.data.cwe Class Hierarchy (Dependency-Check Core 1.2.11 API) - +org.owasp.dependencycheck.data.cwe Class Hierarchy (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cwe/package-use.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cwe/package-use.html index 276ad6092..c991383d1 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cwe/package-use.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/cwe/package-use.html @@ -2,16 +2,16 @@ - + -Uses of Package org.owasp.dependencycheck.data.cwe (Dependency-Check Core 1.2.11 API) - +Uses of Package org.owasp.dependencycheck.data.cwe (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/AbstractTokenizingFilter.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/AbstractTokenizingFilter.html index 590392e8b..baf343a1b 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/AbstractTokenizingFilter.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/AbstractTokenizingFilter.html @@ -2,16 +2,16 @@ - + -AbstractTokenizingFilter (Dependency-Check Core 1.2.11 API) - +AbstractTokenizingFilter (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/AlphaNumericTokenizer.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/AlphaNumericTokenizer.html index 92a0cc4b1..9ffa59903 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/AlphaNumericTokenizer.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/AlphaNumericTokenizer.html @@ -2,16 +2,16 @@ - + -AlphaNumericTokenizer (Dependency-Check Core 1.2.11 API) - +AlphaNumericTokenizer (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/DependencySimilarity.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/DependencySimilarity.html index a3f1a0c9a..be631c4ea 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/DependencySimilarity.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/DependencySimilarity.html @@ -2,16 +2,16 @@ - + -DependencySimilarity (Dependency-Check Core 1.2.11 API) - +DependencySimilarity (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/FieldAnalyzer.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/FieldAnalyzer.html index 0aaf07402..5312c49e0 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/FieldAnalyzer.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/FieldAnalyzer.html @@ -2,16 +2,16 @@ - + -FieldAnalyzer (Dependency-Check Core 1.2.11 API) - +FieldAnalyzer (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/LuceneUtils.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/LuceneUtils.html index 1c4d2449f..f5e092eef 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/LuceneUtils.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/LuceneUtils.html @@ -2,16 +2,16 @@ - + -LuceneUtils (Dependency-Check Core 1.2.11 API) - +LuceneUtils (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/SearchFieldAnalyzer.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/SearchFieldAnalyzer.html index 854763706..22509c3e2 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/SearchFieldAnalyzer.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/SearchFieldAnalyzer.html @@ -2,16 +2,16 @@ - + -SearchFieldAnalyzer (Dependency-Check Core 1.2.11 API) - +SearchFieldAnalyzer (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/TokenPairConcatenatingFilter.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/TokenPairConcatenatingFilter.html index bc2d86ea5..a033d1261 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/TokenPairConcatenatingFilter.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/TokenPairConcatenatingFilter.html @@ -2,16 +2,16 @@ - + -TokenPairConcatenatingFilter (Dependency-Check Core 1.2.11 API) - +TokenPairConcatenatingFilter (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/UrlTokenizingFilter.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/UrlTokenizingFilter.html index d9effaac5..ce42268a2 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/UrlTokenizingFilter.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/UrlTokenizingFilter.html @@ -2,16 +2,16 @@ - + -UrlTokenizingFilter (Dependency-Check Core 1.2.11 API) - +UrlTokenizingFilter (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/class-use/AbstractTokenizingFilter.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/class-use/AbstractTokenizingFilter.html index 7a9d21fac..e11dc6aa1 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/class-use/AbstractTokenizingFilter.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/class-use/AbstractTokenizingFilter.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.data.lucene.AbstractTokenizingFilter (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.data.lucene.AbstractTokenizingFilter (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/class-use/AlphaNumericTokenizer.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/class-use/AlphaNumericTokenizer.html index 213e3abae..3968b70c2 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/class-use/AlphaNumericTokenizer.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/class-use/AlphaNumericTokenizer.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.data.lucene.AlphaNumericTokenizer (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.data.lucene.AlphaNumericTokenizer (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/class-use/DependencySimilarity.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/class-use/DependencySimilarity.html index 9aff3473c..762bb6da5 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/class-use/DependencySimilarity.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/class-use/DependencySimilarity.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.data.lucene.DependencySimilarity (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.data.lucene.DependencySimilarity (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/class-use/FieldAnalyzer.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/class-use/FieldAnalyzer.html index 09efaa687..7fea4a240 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/class-use/FieldAnalyzer.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/class-use/FieldAnalyzer.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.data.lucene.FieldAnalyzer (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.data.lucene.FieldAnalyzer (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/class-use/LuceneUtils.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/class-use/LuceneUtils.html index d94ddcadb..39083d8da 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/class-use/LuceneUtils.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/class-use/LuceneUtils.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.data.lucene.LuceneUtils (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.data.lucene.LuceneUtils (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/class-use/SearchFieldAnalyzer.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/class-use/SearchFieldAnalyzer.html index 01dab15d8..33a69c1e0 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/class-use/SearchFieldAnalyzer.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/class-use/SearchFieldAnalyzer.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.data.lucene.SearchFieldAnalyzer (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.data.lucene.SearchFieldAnalyzer (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/class-use/TokenPairConcatenatingFilter.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/class-use/TokenPairConcatenatingFilter.html index 55f9f2ae4..ab22e65e3 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/class-use/TokenPairConcatenatingFilter.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/class-use/TokenPairConcatenatingFilter.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.data.lucene.TokenPairConcatenatingFilter (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.data.lucene.TokenPairConcatenatingFilter (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/class-use/UrlTokenizingFilter.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/class-use/UrlTokenizingFilter.html index bb73b3f3c..603e707ab 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/class-use/UrlTokenizingFilter.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/class-use/UrlTokenizingFilter.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.data.lucene.UrlTokenizingFilter (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.data.lucene.UrlTokenizingFilter (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/package-frame.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/package-frame.html index 8e6fbd8be..68e9370bb 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/package-frame.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/package-frame.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.data.lucene (Dependency-Check Core 1.2.11 API) - +org.owasp.dependencycheck.data.lucene (Dependency-Check Core 1.3.0 API) + 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 d5fec0d49..07adffa2e 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,16 +2,16 @@ - + -org.owasp.dependencycheck.data.lucene (Dependency-Check Core 1.2.11 API) - +org.owasp.dependencycheck.data.lucene (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/package-tree.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/package-tree.html index eb00fc2a5..caaa937a5 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/package-tree.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/package-tree.html @@ -2,16 +2,16 @@ - + -org.owasp.dependencycheck.data.lucene Class Hierarchy (Dependency-Check Core 1.2.11 API) - +org.owasp.dependencycheck.data.lucene Class Hierarchy (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/package-use.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/package-use.html index a6472dfd5..4f957d5d8 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/package-use.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/lucene/package-use.html @@ -2,16 +2,16 @@ - + -Uses of Package org.owasp.dependencycheck.data.lucene (Dependency-Check Core 1.2.11 API) - +Uses of Package org.owasp.dependencycheck.data.lucene (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nexus/MavenArtifact.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nexus/MavenArtifact.html index 5c8a3ae87..4410113f5 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nexus/MavenArtifact.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nexus/MavenArtifact.html @@ -2,16 +2,16 @@ - + -MavenArtifact (Dependency-Check Core 1.2.11 API) - +MavenArtifact (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nexus/NexusSearch.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nexus/NexusSearch.html index 5b7db2c36..1172eb955 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nexus/NexusSearch.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nexus/NexusSearch.html @@ -2,16 +2,16 @@ - + -NexusSearch (Dependency-Check Core 1.2.11 API) - +NexusSearch (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nexus/class-use/MavenArtifact.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nexus/class-use/MavenArtifact.html index 8c3342b2a..42d535c71 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nexus/class-use/MavenArtifact.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nexus/class-use/MavenArtifact.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.data.nexus.MavenArtifact (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.data.nexus.MavenArtifact (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nexus/class-use/NexusSearch.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nexus/class-use/NexusSearch.html index c36313227..f8e4032b9 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nexus/class-use/NexusSearch.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nexus/class-use/NexusSearch.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.data.nexus.NexusSearch (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.data.nexus.NexusSearch (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nexus/package-frame.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nexus/package-frame.html index 7d8fbb4d2..5ab8f28bb 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nexus/package-frame.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nexus/package-frame.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.data.nexus (Dependency-Check Core 1.2.11 API) - +org.owasp.dependencycheck.data.nexus (Dependency-Check Core 1.3.0 API) + 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 dd3c4f996..427ad45de 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,16 +2,16 @@ - + -org.owasp.dependencycheck.data.nexus (Dependency-Check Core 1.2.11 API) - +org.owasp.dependencycheck.data.nexus (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nexus/package-tree.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nexus/package-tree.html index 914d2ad49..e22153c73 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nexus/package-tree.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nexus/package-tree.html @@ -2,16 +2,16 @@ - + -org.owasp.dependencycheck.data.nexus Class Hierarchy (Dependency-Check Core 1.2.11 API) - +org.owasp.dependencycheck.data.nexus Class Hierarchy (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nexus/package-use.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nexus/package-use.html index 5688b754e..8adbee299 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nexus/package-use.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nexus/package-use.html @@ -2,16 +2,16 @@ - + -Uses of Package org.owasp.dependencycheck.data.nexus (Dependency-Check Core 1.2.11 API) - +Uses of Package org.owasp.dependencycheck.data.nexus (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/NugetPackage.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/NugetPackage.html index 969e6aa05..b0376d746 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/NugetPackage.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/NugetPackage.html @@ -2,16 +2,16 @@ - + -NugetPackage (Dependency-Check Core 1.2.11 API) - +NugetPackage (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/NuspecParseException.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/NuspecParseException.html index c3647103b..8bf14675d 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/NuspecParseException.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/NuspecParseException.html @@ -2,16 +2,16 @@ - + -NuspecParseException (Dependency-Check Core 1.2.11 API) - +NuspecParseException (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/NuspecParser.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/NuspecParser.html index 31ca435f7..654698893 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/NuspecParser.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/NuspecParser.html @@ -2,16 +2,16 @@ - + -NuspecParser (Dependency-Check Core 1.2.11 API) - +NuspecParser (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/XPathNuspecParser.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/XPathNuspecParser.html index 1392510f2..38d127229 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/XPathNuspecParser.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/XPathNuspecParser.html @@ -2,16 +2,16 @@ - + -XPathNuspecParser (Dependency-Check Core 1.2.11 API) - +XPathNuspecParser (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/class-use/NugetPackage.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/class-use/NugetPackage.html index 892890301..0b9096aa6 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/class-use/NugetPackage.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/class-use/NugetPackage.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.data.nuget.NugetPackage (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.data.nuget.NugetPackage (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/class-use/NuspecParseException.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/class-use/NuspecParseException.html index 6d352a029..29aa07ac1 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/class-use/NuspecParseException.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/class-use/NuspecParseException.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.data.nuget.NuspecParseException (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.data.nuget.NuspecParseException (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/class-use/NuspecParser.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/class-use/NuspecParser.html index ad06273f0..61965de29 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/class-use/NuspecParser.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/class-use/NuspecParser.html @@ -2,16 +2,16 @@ - + -Uses of Interface org.owasp.dependencycheck.data.nuget.NuspecParser (Dependency-Check Core 1.2.11 API) - +Uses of Interface org.owasp.dependencycheck.data.nuget.NuspecParser (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/class-use/XPathNuspecParser.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/class-use/XPathNuspecParser.html index 684ad14fe..1f49c4ce9 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/class-use/XPathNuspecParser.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/class-use/XPathNuspecParser.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.data.nuget.XPathNuspecParser (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.data.nuget.XPathNuspecParser (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/package-frame.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/package-frame.html index 4752d2f93..48fb9bf48 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/package-frame.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/package-frame.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.data.nuget (Dependency-Check Core 1.2.11 API) - +org.owasp.dependencycheck.data.nuget (Dependency-Check Core 1.3.0 API) + 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 b5f4568ee..3befb77fd 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,16 +2,16 @@ - + -org.owasp.dependencycheck.data.nuget (Dependency-Check Core 1.2.11 API) - +org.owasp.dependencycheck.data.nuget (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/package-tree.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/package-tree.html index 6897918dd..0ab96ba98 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/package-tree.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/package-tree.html @@ -2,16 +2,16 @@ - + -org.owasp.dependencycheck.data.nuget Class Hierarchy (Dependency-Check Core 1.2.11 API) - +org.owasp.dependencycheck.data.nuget Class Hierarchy (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/package-use.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/package-use.html index 270dc4922..53f8a885c 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/package-use.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nuget/package-use.html @@ -2,16 +2,16 @@ - + -Uses of Package org.owasp.dependencycheck.data.nuget (Dependency-Check Core 1.2.11 API) - +Uses of Package org.owasp.dependencycheck.data.nuget (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/ConnectionFactory.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/ConnectionFactory.html index bcd1185f0..d57047d36 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/ConnectionFactory.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/ConnectionFactory.html @@ -2,16 +2,16 @@ - + -ConnectionFactory (Dependency-Check Core 1.2.11 API) - +ConnectionFactory (Dependency-Check Core 1.3.0 API) + @@ -99,9 +99,8 @@
    public final class ConnectionFactory
     extends Object
    -
    Loads the configured database driver and returns the database connection. If the embedded H2 database is used - obtaining a connection will ensure the database file exists and that the appropriate table structure has been - created.
    +
    Loads the configured database driver and returns the database connection. If the embedded H2 database is used obtaining a + connection will ensure the database file exists and that the appropriate table structure has been created.
    Author:
    Jeremy Long
    @@ -134,6 +133,12 @@ extends Resource location for SQL file used to create the database schema. + +static String +DB_STRUCTURE_UPDATE_RESOURCE +
    Resource location for SQL file used to create the database schema.
    + + @@ -202,7 +207,7 @@ extends -
      + + + + +
        +
      • +

        DB_STRUCTURE_UPDATE_RESOURCE

        +
        public static final String DB_STRUCTURE_UPDATE_RESOURCE
        +
        Resource location for SQL file used to create the database schema.
        +
        See Also:
        Constant Field Values
        +
      • +
    @@ -226,8 +242,8 @@ extends DatabaseException -
    Initializes the connection factory. Ensuring that the appropriate drivers are loaded and that a connection can be - made successfully.
    +
    Initializes the connection factory. Ensuring that the appropriate drivers are loaded and that a connection can be made + successfully.
    Throws:
    DatabaseException - thrown if we are unable to connect to the database
    @@ -240,8 +256,8 @@ extends Cleans up resources and unloads any registered database drivers. This needs to be called to ensure the driver is - unregistered prior to the finalize method being called as during shutdown the class loader used to load the - driver may be unloaded prior to the driver being de-registered. + unregistered prior to the finalize method being called as during shutdown the class loader used to load the driver may be + unloaded prior to the driver being de-registered. diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/CveDB.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/CveDB.html index 1b1498dac..40d50ad07 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/CveDB.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/CveDB.html @@ -2,16 +2,16 @@ - + -CveDB (Dependency-Check Core 1.2.11 API) - +CveDB (Dependency-Check Core 1.3.0 API) + @@ -141,28 +141,42 @@ extends void +addCpe(String cpe, + String vendor, + String product) +
    Merges CPE entries into the database.
    + + + +void cleanupDatabase()
    It is possible that orphaned rows may be generated during database updates.
    - + void close()
    Closes the DB4O database.
    - + void commit()
    Commits all completed transactions.
    - + boolean dataExists()
    Checks to see if data exists so that analysis can be performed.
    + +void +deleteUnusedCpe() +
    Deletes unused dictionary entries from the database.
    + + protected void finalize() @@ -418,7 +432,7 @@ extends -
      +
      • cleanupDatabase

        public void cleanupDatabase()
        @@ -426,6 +440,29 @@ extends + + +
          +
        • +

          deleteUnusedCpe

          +
          public void deleteUnusedCpe()
          +
          Deletes unused dictionary entries from the database.
          +
        • +
        + + + +
          +
        • +

          addCpe

          +
          public void addCpe(String cpe,
          +          String vendor,
          +          String product)
          +
          Merges CPE entries into the database.
          +
          Parameters:
          cpe - the CPE identifier
          vendor - the CPE vendor
          product - the CPE product
          +
        • +
      diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/DatabaseException.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/DatabaseException.html index d172ec6da..6ea49b5c2 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/DatabaseException.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/DatabaseException.html @@ -2,16 +2,16 @@ - + -DatabaseException (Dependency-Check Core 1.2.11 API) - +DatabaseException (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/DatabaseProperties.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/DatabaseProperties.html index 3b57c667c..130b3ad25 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/DatabaseProperties.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/DatabaseProperties.html @@ -2,16 +2,16 @@ - + -DatabaseProperties (Dependency-Check Core 1.2.11 API) - +DatabaseProperties (Dependency-Check Core 1.3.0 API) + @@ -122,23 +122,34 @@ extends static String -LAST_UPDATED -
      The properties file key for the last updated field - used to store the last updated time of the Modified NVD CVE - xml file.
      +LAST_CPE_UPDATE +
      The key for the last time the CPE data was updated.
      static String +LAST_UPDATED +
      The properties file key for the last updated field - used to store the last updated time of the Modified NVD CVE xml file.
      + + + +static String LAST_UPDATED_BASE
      Stores the last updated time for each of the NVD CVE files.
      - + static String MODIFIED
      Modified key word, used as a key to store information about the modified file (i.e.
      + +static String +VERSION +
      The key for the database schema version.
      + +
    @@ -187,7 +198,7 @@ extends void -save(NvdCveInfo updatedValue) +save(NvdCveInfo updatedValue)
    Saves the last updated information to the properties file.
    @@ -227,8 +238,8 @@ extends

    MODIFIED

    public static final String MODIFIED
    -
    Modified key word, used as a key to store information about the modified file (i.e. the containing the last 8 - days of updates)..
    +
    Modified key word, used as a key to store information about the modified file (i.e. the containing the last 8 days of + updates)..
    See Also:
    Constant Field Values
    @@ -239,23 +250,44 @@ extends

    LAST_UPDATED

    public static final String LAST_UPDATED
    -
    The properties file key for the last updated field - used to store the last updated time of the Modified NVD CVE - xml file.
    +
    The properties file key for the last updated field - used to store the last updated time of the Modified NVD CVE xml file.
    See Also:
    Constant Field Values
    -
      +
      • LAST_UPDATED_BASE

        public static final String LAST_UPDATED_BASE
        -
        Stores the last updated time for each of the NVD CVE files. These timestamps should be updated if we process the - modified file within 7 days of the last update.
        +
        Stores the last updated time for each of the NVD CVE files. These timestamps should be updated if we process the modified + file within 7 days of the last update.
        See Also:
        Constant Field Values
      + + + +
        +
      • +

        LAST_CPE_UPDATE

        +
        public static final String LAST_CPE_UPDATE
        +
        The key for the last time the CPE data was updated.
        +
        See Also:
        Constant Field Values
        +
      • +
      + + + +
    @@ -275,13 +307,13 @@ extends Returns:
    whether or not any properties are set
    -
    +
    • save

      -
      public void save(NvdCveInfo updatedValue)
      +
      public void save(NvdCveInfo updatedValue)
                 throws UpdateException
      Saves the last updated information to the properties file.
      Parameters:
      updatedValue - the updated NVD CVE entry
      @@ -311,8 +343,7 @@ extends

      getProperty

      public String getProperty(String key)
      -
      Returns the property value for the given key. If the key is not contained in the underlying properties null is - returned.
      +
      Returns the property value for the given key. If the key is not contained in the underlying properties null is returned.
      Parameters:
      key - the property key
      Returns:
      the value of the property
    • @@ -325,8 +356,8 @@ extends String getProperty(String key, String defaultValue) -
      Returns the property value for the given key. If the key is not contained in the underlying properties the - default value is returned.
      +
      Returns the property value for the given key. If the key is not contained in the underlying properties the default value is + returned.
      Parameters:
      key - the property key
      defaultValue - the default value
      Returns:
      the value of the property
      @@ -349,8 +380,8 @@ extends

      getMetaData

      public Map<String,String> getMetaData()
      -
      Returns a map of the meta data from the database properties. This primarily contains timestamps of when the NVD - CVE information was last updated.
      +
      Returns a map of the meta data from the database properties. This primarily contains timestamps of when the NVD CVE + information was last updated.
      Returns:
      a map of the database meta data
    diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/DriverLoadException.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/DriverLoadException.html index 3a5591fd1..a30288379 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/DriverLoadException.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/DriverLoadException.html @@ -2,16 +2,16 @@ - + -DriverLoadException (Dependency-Check Core 1.2.11 API) - +DriverLoadException (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/DriverLoader.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/DriverLoader.html index bc5ab289a..3fa1308e7 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/DriverLoader.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/DriverLoader.html @@ -2,16 +2,16 @@ - + -DriverLoader (Dependency-Check Core 1.2.11 API) - +DriverLoader (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/class-use/ConnectionFactory.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/class-use/ConnectionFactory.html index a1dac53c5..6c0118bb6 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/class-use/ConnectionFactory.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/class-use/ConnectionFactory.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.data.nvdcve.ConnectionFactory (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.data.nvdcve.ConnectionFactory (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/class-use/CveDB.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/class-use/CveDB.html index cd32b0ff9..72fceadb6 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/class-use/CveDB.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/class-use/CveDB.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.data.nvdcve.CveDB (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.data.nvdcve.CveDB (Dependency-Check Core 1.3.0 API) + @@ -83,17 +83,17 @@ -org.owasp.dependencycheck.data.update.task +org.owasp.dependencycheck.data.update -
    A collection of callable/runnable tasks used to speed up the update process.
    +
    Contains classes used to update the data stores.

    + + The UpdateService will load, any correctly defined CachedWebDataSource(s) and call update() on them.
    -org.owasp.dependencycheck.data.update.xml +org.owasp.dependencycheck.data.update.nvd -
    Contains classes used to parse the NVD CVE XML file.

    - - The basic use is that the Importer is called to import an NVD CVE file.
    +
    Contains classes used to download, parse, and load the NVD CVE data from NIST into the local database.

    @@ -121,40 +121,30 @@ -
  • +
  • -

    Uses of CveDB in org.owasp.dependencycheck.data.update.task

    - - +

    Uses of CveDB in org.owasp.dependencycheck.data.update

    +
    Constructors in org.owasp.dependencycheck.data.update.task with parameters of type CveDB 
    + - + + - - - - + +
    Methods in org.owasp.dependencycheck.data.update that return CveDB 
    Constructor and DescriptionModifier and TypeMethod and Description
    DownloadTask(NvdCveInfo nvdCveInfo, - ExecutorService processor, - CveDB cveDB, - Settings settings) -
    Simple constructor for the callable download task.
    -
    ProcessTask(CveDB cveDB, - DownloadTask filePair, - Settings settings) -
    Constructs a new ProcessTask used to process an NVD CVE update.
    -
    protected CveDBBaseUpdater.getCveDB() 
  • -
  • +
  • -

    Uses of CveDB in org.owasp.dependencycheck.data.update.xml

    +

    Uses of CveDB in org.owasp.dependencycheck.data.update.nvd

    - + @@ -162,12 +152,35 @@ -
    Methods in org.owasp.dependencycheck.data.update.xml with parameters of type CveDB Methods in org.owasp.dependencycheck.data.update.nvd with parameters of type CveDB 
    Modifier and Type Method and Description
    voidNvdCve20Handler.setCveDB(CveDB db) +NvdCve20Handler.setCveDB(CveDB db)
    Sets the cveDB.
    + + + + + + + + + + + + + +
    Constructors in org.owasp.dependencycheck.data.update.nvd with parameters of type CveDB 
    Constructor and Description
    DownloadTask(NvdCveInfo nvdCveInfo, + ExecutorService processor, + CveDB cveDB, + Settings settings) +
    Simple constructor for the callable download task.
    +
    ProcessTask(CveDB cveDB, + DownloadTask filePair, + Settings settings) +
    Constructs a new ProcessTask used to process an NVD CVE update.
    +
  • diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/class-use/DatabaseException.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/class-use/DatabaseException.html index 3afcb37e3..6a6e30d56 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/class-use/DatabaseException.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/class-use/DatabaseException.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.data.nvdcve.DatabaseException (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.data.nvdcve.DatabaseException (Dependency-Check Core 1.3.0 API) + @@ -103,9 +103,9 @@ -org.owasp.dependencycheck.data.update.task +org.owasp.dependencycheck.data.update.nvd -
    A collection of callable/runnable tasks used to speed up the update process.
    +
    Contains classes used to download, parse, and load the NVD CVE data from NIST into the local database.

    @@ -266,12 +266,12 @@ -
  • +
  • -

    Uses of DatabaseException in org.owasp.dependencycheck.data.update.task

    +

    Uses of DatabaseException in org.owasp.dependencycheck.data.update.nvd

    - + @@ -279,7 +279,7 @@ - diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/class-use/DatabaseProperties.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/class-use/DatabaseProperties.html index b7c9b5878..f4a1c9f6b 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/class-use/DatabaseProperties.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/class-use/DatabaseProperties.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.data.nvdcve.DatabaseProperties (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.data.nvdcve.DatabaseProperties (Dependency-Check Core 1.3.0 API) + @@ -126,6 +126,19 @@

    Uses of DatabaseProperties in org.owasp.dependencycheck.data.update

    Methods in org.owasp.dependencycheck.data.update.task that throw DatabaseException Methods in org.owasp.dependencycheck.data.update.nvd that throw DatabaseException 
    Modifier and Type Method and Description
    protected voidProcessTask.importXML(File file, +ProcessTask.importXML(File file, File oldVersion)
    Imports the NVD CVE XML File into the Lucene Index.
    + + + + + + + + + + + +
    Methods in org.owasp.dependencycheck.data.update that return DatabaseProperties 
    Modifier and TypeMethod and Description
    protected DatabasePropertiesBaseUpdater.getProperties() 
    + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/class-use/DriverLoadException.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/class-use/DriverLoadException.html index 0fed4ac44..82a1a1711 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/class-use/DriverLoadException.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/class-use/DriverLoadException.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.data.nvdcve.DriverLoadException (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.data.nvdcve.DriverLoadException (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/class-use/DriverLoader.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/class-use/DriverLoader.html index c8b0ee06b..33e602abf 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/class-use/DriverLoader.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/class-use/DriverLoader.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.data.nvdcve.DriverLoader (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.data.nvdcve.DriverLoader (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/package-frame.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/package-frame.html index ef7f502b6..7c3e3c0c5 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/package-frame.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/package-frame.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.data.nvdcve (Dependency-Check Core 1.2.11 API) - +org.owasp.dependencycheck.data.nvdcve (Dependency-Check Core 1.3.0 API) + 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 609ea00ef..9b3f164d0 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,16 +2,16 @@ - + -org.owasp.dependencycheck.data.nvdcve (Dependency-Check Core 1.2.11 API) - +org.owasp.dependencycheck.data.nvdcve (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/package-tree.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/package-tree.html index 021ee676b..aff93fc8a 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/package-tree.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/package-tree.html @@ -2,16 +2,16 @@ - + -org.owasp.dependencycheck.data.nvdcve Class Hierarchy (Dependency-Check Core 1.2.11 API) - +org.owasp.dependencycheck.data.nvdcve Class Hierarchy (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/package-use.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/package-use.html index 5ba98e079..1076bb354 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/package-use.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/nvdcve/package-use.html @@ -2,16 +2,16 @@ - + -Uses of Package org.owasp.dependencycheck.data.nvdcve (Dependency-Check Core 1.2.11 API) - +Uses of Package org.owasp.dependencycheck.data.nvdcve (Dependency-Check Core 1.3.0 API) + @@ -109,26 +109,18 @@ - + - - - - - + + + + - + @@ -237,45 +234,28 @@
    Methods in org.owasp.dependencycheck.data.update with parameters of type DatabaseProperties 
    Modifier and Type
    org.owasp.dependencycheck.data.update.taskorg.owasp.dependencycheck.data.update.nvd -
    A collection of callable/runnable tasks used to speed up the update process.
    +
    Contains classes used to download, parse, and load the NVD CVE data from NIST into the local database.

    org.owasp.dependencycheck.data.update.xml -
    Contains classes used to parse the NVD CVE XML file.

    - - The basic use is that the Importer is called to import an NVD CVE file.
    -
    org.owasp.dependencycheck.reporting
    Contains classes used to generate reports.
    org.owasp.dependencycheck.utils
    Includes various utility classes such as a Settings wrapper, a Checksum utility, etc.
    @@ -225,11 +217,16 @@
    CveDB +
    The database holding information about the NVD CVE data.
    +
    DatabaseException
    An exception thrown if an operation against the database fails.
    DatabaseProperties
    This is a wrapper around a set of properties that are stored in the database.
  • -
  • +
  • - + - -
    Classes in org.owasp.dependencycheck.data.nvdcve used by org.owasp.dependencycheck.data.update.task Classes in org.owasp.dependencycheck.data.nvdcve used by org.owasp.dependencycheck.data.update.nvd 
    Class and Description
    CveDB +CveDB
    The database holding information about the NVD CVE data.
    DatabaseException +DatabaseException
    An exception thrown if an operation against the database fails.
  • -
  • - - - - - - - - - - - - -
    Classes in org.owasp.dependencycheck.data.nvdcve used by org.owasp.dependencycheck.data.update.xml 
    Class and Description
    CveDB -
    The database holding information about the NVD CVE data.
    -
    -
  • diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/BaseUpdater.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/BaseUpdater.html new file mode 100644 index 000000000..5fcecefa8 --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/BaseUpdater.html @@ -0,0 +1,312 @@ + + + + + + +BaseUpdater (Dependency-Check Core 1.3.0 API) + + + + + + + + + + + +
    +
    org.owasp.dependencycheck.data.update
    +

    Class BaseUpdater

    +
    +
    + +
    + +
    +
    + +
    +
    +
      +
    • + +
        +
      • + + +

        Constructor Detail

        + + + +
          +
        • +

          BaseUpdater

          +
          public BaseUpdater()
          +
        • +
        +
      • +
      + +
        +
      • + + +

        Method Detail

        + + + +
          +
        • +

          getCveDB

          +
          protected CveDB getCveDB()
          +
        • +
        + + + + + + + +
          +
        • +

          closeDataStores

          +
          protected void closeDataStores()
          +
          Closes the CVE and CPE data stores.
          +
        • +
        + + + +
          +
        • +

          openDataStores

          +
          protected final void openDataStores()
          +                             throws UpdateException
          +
          Opens the data store.
          +
          Throws:
          +
          UpdateException - thrown if a data store cannot be opened
          +
        • +
        +
      • +
      +
    • +
    +
    +
    + + + + + +

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

    + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/CachedWebDataSource.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/CachedWebDataSource.html index 9ceec85c2..11d869b2e 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/CachedWebDataSource.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/CachedWebDataSource.html @@ -2,16 +2,16 @@ - + -CachedWebDataSource (Dependency-Check Core 1.2.11 API) - +CachedWebDataSource (Dependency-Check Core 1.3.0 API) + @@ -37,8 +37,8 @@
    + + + + + +

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

    + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/NvdCve12Handler.Element.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/NvdCve12Handler.Element.html new file mode 100644 index 000000000..b2a89544e --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/NvdCve12Handler.Element.html @@ -0,0 +1,479 @@ + + + + + + +NvdCve12Handler.Element (Dependency-Check Core 1.3.0 API) + + + + + + + + + + + +
    +
    org.owasp.dependencycheck.data.update.nvd
    +

    Class NvdCve12Handler.Element

    +
    +
    +
      +
    • java.lang.Object
    • +
    • +
        +
      • org.owasp.dependencycheck.data.update.nvd.NvdCve12Handler.Element
      • +
      +
    • +
    +
    +
      +
    • +
      +
      Enclosing class:
      +
      NvdCve12Handler
      +
      +
      +
      +
      protected static class NvdCve12Handler.Element
      +extends Object
      +
      A simple class to maintain information about the current element while parsing the NVD CVE XML.
      +
    • +
    +
    +
    +
      +
    • + +
        +
      • + + +

        Field Summary

        + + + + + + + + + + + + + + + + + + + + + + + + + + +
        Fields 
        Modifier and TypeField and Description
        static StringENTRY +
        A node type in the NVD CVE Schema 1.2.
        +
        static StringNVD +
        A node type in the NVD CVE Schema 1.2.
        +
        static StringPROD +
        A node type in the NVD CVE Schema 1.2.
        +
        static StringVERS +
        A node type in the NVD CVE Schema 1.2.
        +
        static StringVULN_SOFTWARE +
        A node type in the NVD CVE Schema 1.2.
        +
        +
      • +
      + +
        +
      • + + +

        Constructor Summary

        + + + + + + + + + + +
        Constructors 
        ModifierConstructor and Description
        protected NvdCve12Handler.Element() 
        +
      • +
      + + +
    • +
    +
    +
    +
      +
    • + + + +
        +
      • + + +

        Constructor Detail

        + + + +
          +
        • +

          NvdCve12Handler.Element

          +
          protected NvdCve12Handler.Element()
          +
        • +
        +
      • +
      + +
        +
      • + + +

        Method Detail

        + + + +
          +
        • +

          getNode

          +
          public String getNode()
          +
          Gets the value of node.
          +
          Returns:
          the value of node
          +
        • +
        + + + +
          +
        • +

          setNode

          +
          public void setNode(String node)
          +
          Sets the value of node.
          +
          Parameters:
          node - new value of node
          +
        • +
        + + + +
          +
        • +

          isNVDNode

          +
          public boolean isNVDNode()
          +
          Checks if the handler is at the NVD node.
          +
          Returns:
          true or false
          +
        • +
        + + + +
          +
        • +

          isEntryNode

          +
          public boolean isEntryNode()
          +
          Checks if the handler is at the ENTRY node.
          +
          Returns:
          true or false
          +
        • +
        + + + +
          +
        • +

          isVulnSoftwareNode

          +
          public boolean isVulnSoftwareNode()
          +
          Checks if the handler is at the VULN_SOFTWARE node.
          +
          Returns:
          true or false
          +
        • +
        + + + +
          +
        • +

          isProdNode

          +
          public boolean isProdNode()
          +
          Checks if the handler is at the PROD node.
          +
          Returns:
          true or false
          +
        • +
        + + + +
          +
        • +

          isVersNode

          +
          public boolean isVersNode()
          +
          Checks if the handler is at the VERS node.
          +
          Returns:
          true or false
          +
        • +
        +
      • +
      +
    • +
    +
    +
    + + + + + +

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

    + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/NvdCve12Handler.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/NvdCve12Handler.html new file mode 100644 index 000000000..34e69386a --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/NvdCve12Handler.html @@ -0,0 +1,356 @@ + + + + + + +NvdCve12Handler (Dependency-Check Core 1.3.0 API) + + + + + + + + + + + +
    +
    org.owasp.dependencycheck.data.update.nvd
    +

    Class NvdCve12Handler

    +
    +
    + +
    +
      +
    • +
      +
      All Implemented Interfaces:
      +
      ContentHandler, DTDHandler, EntityResolver, ErrorHandler
      +
      +
      +
      +
      public class NvdCve12Handler
      +extends org.xml.sax.helpers.DefaultHandler
      +
      A SAX Handler that will parse the NVD CVE XML (schema version 1.2). This parses the xml and retrieves a listing of + CPEs that have previous versions specified. The previous version information is not in the 2.0 version of the schema + and is useful to ensure accurate identification (or at least complete).
      +
      Author:
      +
      Jeremy Long
      +
    • +
    +
    +
    + +
    +
    + +
    +
    + + + + + +

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

    + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/NvdCve20Handler.Element.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/NvdCve20Handler.Element.html new file mode 100644 index 000000000..27dddd051 --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/NvdCve20Handler.Element.html @@ -0,0 +1,819 @@ + + + + + + +NvdCve20Handler.Element (Dependency-Check Core 1.3.0 API) + + + + + + + + + + + +
    +
    org.owasp.dependencycheck.data.update.nvd
    +

    Class NvdCve20Handler.Element

    +
    +
    +
      +
    • java.lang.Object
    • +
    • +
        +
      • org.owasp.dependencycheck.data.update.nvd.NvdCve20Handler.Element
      • +
      +
    • +
    +
    +
      +
    • +
      +
      Enclosing class:
      +
      NvdCve20Handler
      +
      +
      +
      +
      protected static class NvdCve20Handler.Element
      +extends Object
      +
      A simple class to maintain information about the current element while parsing the NVD CVE XML.
      +
    • +
    +
    +
    + +
    +
    +
      +
    • + + + +
        +
      • + + +

        Constructor Detail

        + + + +
          +
        • +

          NvdCve20Handler.Element

          +
          protected NvdCve20Handler.Element()
          +
        • +
        +
      • +
      + +
        +
      • + + +

        Method Detail

        + + + +
          +
        • +

          getNode

          +
          public String getNode()
          +
          Gets the value of node.
          +
          Returns:
          the value of node
          +
        • +
        + + + +
          +
        • +

          setNode

          +
          public void setNode(String node)
          +
          Sets the value of node.
          +
          Parameters:
          node - new value of node
          +
        • +
        + + + +
          +
        • +

          isNVDNode

          +
          public boolean isNVDNode()
          +
          Checks if the handler is at the NVD node.
          +
          Returns:
          true or false
          +
        • +
        + + + +
          +
        • +

          isEntryNode

          +
          public boolean isEntryNode()
          +
          Checks if the handler is at the ENTRY node.
          +
          Returns:
          true or false
          +
        • +
        + + + +
          +
        • +

          isVulnProductNode

          +
          public boolean isVulnProductNode()
          +
          Checks if the handler is at the VULN_PRODUCT node.
          +
          Returns:
          true or false
          +
        • +
        + + + +
          +
        • +

          isVulnReferencesNode

          +
          public boolean isVulnReferencesNode()
          +
          Checks if the handler is at the REFERENCES node.
          +
          Returns:
          true or false
          +
        • +
        + + + +
          +
        • +

          isVulnReferenceNode

          +
          public boolean isVulnReferenceNode()
          +
          Checks if the handler is at the REFERENCE node.
          +
          Returns:
          true or false
          +
        • +
        + + + +
          +
        • +

          isVulnSourceNode

          +
          public boolean isVulnSourceNode()
          +
          Checks if the handler is at the VULN_SOURCE node.
          +
          Returns:
          true or false
          +
        • +
        + + + +
          +
        • +

          isVulnSummaryNode

          +
          public boolean isVulnSummaryNode()
          +
          Checks if the handler is at the VULN_SUMMARY node.
          +
          Returns:
          true or false
          +
        • +
        + + + +
          +
        • +

          isVulnCWENode

          +
          public boolean isVulnCWENode()
          +
          Checks if the handler is at the VULN_CWE node.
          +
          Returns:
          true or false
          +
        • +
        + + + +
          +
        • +

          isCVSSScoreNode

          +
          public boolean isCVSSScoreNode()
          +
          Checks if the handler is at the CVSS_SCORE node.
          +
          Returns:
          true or false
          +
        • +
        + + + +
          +
        • +

          isCVSSAccessVectorNode

          +
          public boolean isCVSSAccessVectorNode()
          +
          Checks if the handler is at the CVSS_ACCESS_VECTOR node.
          +
          Returns:
          true or false
          +
        • +
        + + + +
          +
        • +

          isCVSSAccessComplexityNode

          +
          public boolean isCVSSAccessComplexityNode()
          +
          Checks if the handler is at the CVSS_ACCESS_COMPLEXITY node.
          +
          Returns:
          true or false
          +
        • +
        + + + +
          +
        • +

          isCVSSAuthenticationNode

          +
          public boolean isCVSSAuthenticationNode()
          +
          Checks if the handler is at the CVSS_AUTHENTICATION node.
          +
          Returns:
          true or false
          +
        • +
        + + + +
          +
        • +

          isCVSSConfidentialityImpactNode

          +
          public boolean isCVSSConfidentialityImpactNode()
          +
          Checks if the handler is at the CVSS_CONFIDENTIALITY_IMPACT node.
          +
          Returns:
          true or false
          +
        • +
        + + + +
          +
        • +

          isCVSSIntegrityImpactNode

          +
          public boolean isCVSSIntegrityImpactNode()
          +
          Checks if the handler is at the CVSS_INTEGRITY_IMPACT node.
          +
          Returns:
          true or false
          +
        • +
        + + + +
          +
        • +

          isCVSSAvailabilityImpactNode

          +
          public boolean isCVSSAvailabilityImpactNode()
          +
          Checks if the handler is at the CVSS_AVAILABILITY_IMPACT node.
          +
          Returns:
          true or false
          +
        • +
        +
      • +
      +
    • +
    +
    +
    + + + + + +

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

    + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/NvdCve20Handler.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/NvdCve20Handler.html new file mode 100644 index 000000000..cd1a74c62 --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/NvdCve20Handler.html @@ -0,0 +1,430 @@ + + + + + + +NvdCve20Handler (Dependency-Check Core 1.3.0 API) + + + + + + + + + + + +
    +
    org.owasp.dependencycheck.data.update.nvd
    +

    Class NvdCve20Handler

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

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

    + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/NvdCveInfo.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/NvdCveInfo.html new file mode 100644 index 000000000..e59f71d53 --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/NvdCveInfo.html @@ -0,0 +1,418 @@ + + + + + + +NvdCveInfo (Dependency-Check Core 1.3.0 API) + + + + + + + + + + + +
    +
    org.owasp.dependencycheck.data.update.nvd
    +

    Class NvdCveInfo

    +
    +
    +
      +
    • java.lang.Object
    • +
    • +
        +
      • org.owasp.dependencycheck.data.update.nvd.NvdCveInfo
      • +
      +
    • +
    +
    +
      +
    • +
      +
      +
      public class NvdCveInfo
      +extends Object
      +
      A pojo that contains the Url and timestamp of the current NvdCve XML files.
      +
      Author:
      +
      Jeremy Long
      +
    • +
    +
    +
    + +
    +
    +
      +
    • + +
        +
      • + + +

        Constructor Detail

        + + + +
          +
        • +

          NvdCveInfo

          +
          public NvdCveInfo()
          +
        • +
        +
      • +
      + +
        +
      • + + +

        Method Detail

        + + + +
          +
        • +

          getId

          +
          public String getId()
          +
          Get the value of id.
          +
          Returns:
          the value of id
          +
        • +
        + + + +
          +
        • +

          setId

          +
          public void setId(String id)
          +
          Set the value of id.
          +
          Parameters:
          id - new value of id
          +
        • +
        + + + +
          +
        • +

          getUrl

          +
          public String getUrl()
          +
          Get the value of url.
          +
          Returns:
          the value of url
          +
        • +
        + + + +
          +
        • +

          setUrl

          +
          public void setUrl(String url)
          +
          Set the value of url.
          +
          Parameters:
          url - new value of url
          +
        • +
        + + + +
          +
        • +

          getOldSchemaVersionUrl

          +
          public String getOldSchemaVersionUrl()
          +
          Get the value of oldSchemaVersionUrl.
          +
          Returns:
          the value of oldSchemaVersionUrl
          +
        • +
        + + + +
          +
        • +

          setOldSchemaVersionUrl

          +
          public void setOldSchemaVersionUrl(String oldSchemaVersionUrl)
          +
          Set the value of oldSchemaVersionUrl.
          +
          Parameters:
          oldSchemaVersionUrl - new value of oldSchemaVersionUrl
          +
        • +
        + + + +
          +
        • +

          getTimestamp

          +
          public long getTimestamp()
          +
          Get the value of timestamp - epoch time.
          +
          Returns:
          the value of timestamp - epoch time
          +
        • +
        + + + +
          +
        • +

          setTimestamp

          +
          public void setTimestamp(long timestamp)
          +
          Set the value of timestamp - epoch time.
          +
          Parameters:
          timestamp - new value of timestamp - epoch time
          +
        • +
        + + + +
          +
        • +

          getNeedsUpdate

          +
          public boolean getNeedsUpdate()
          +
          Get the value of needsUpdate.
          +
          Returns:
          the value of needsUpdate
          +
        • +
        + + + +
          +
        • +

          setNeedsUpdate

          +
          public void setNeedsUpdate(boolean needsUpdate)
          +
          Set the value of needsUpdate.
          +
          Parameters:
          needsUpdate - new value of needsUpdate
          +
        • +
        +
      • +
      +
    • +
    +
    +
    + + + + + +

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

    + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/ProcessTask.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/ProcessTask.html new file mode 100644 index 000000000..34f0c9a13 --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/ProcessTask.html @@ -0,0 +1,352 @@ + + + + + + +ProcessTask (Dependency-Check Core 1.3.0 API) + + + + + + + + + + + +
    +
    org.owasp.dependencycheck.data.update.nvd
    +

    Class ProcessTask

    +
    +
    +
      +
    • java.lang.Object
    • +
    • +
        +
      • org.owasp.dependencycheck.data.update.nvd.ProcessTask
      • +
      +
    • +
    +
    +
      +
    • +
      +
      All Implemented Interfaces:
      +
      Callable<ProcessTask>
      +
      +
      +
      +
      public class ProcessTask
      +extends Object
      +implements Callable<ProcessTask>
      +
      A callable task that will process a given set of NVD CVE xml files and update the Cve Database accordingly.
      +
      Author:
      +
      Jeremy Long
      +
    • +
    +
    +
    + +
    +
    +
      +
    • + +
        +
      • + + +

        Constructor Detail

        + + + +
          +
        • +

          ProcessTask

          +
          public ProcessTask(CveDB cveDB,
          +           DownloadTask filePair,
          +           Settings settings)
          +
          Constructs a new ProcessTask used to process an NVD CVE update.
          +
          Parameters:
          cveDB - the data store object
          filePair - the download task that contains the URL references to download
          settings - a reference to the global settings object; this is necessary so that when the thread is started the + dependencies have a correct reference to the global settings.
          +
        • +
        +
      • +
      + + +
    • +
    +
    +
    + + + + + +

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

    + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/UpdateableNvdCve.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/UpdateableNvdCve.html new file mode 100644 index 000000000..e0eeb2052 --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/UpdateableNvdCve.html @@ -0,0 +1,507 @@ + + + + + + +UpdateableNvdCve (Dependency-Check Core 1.3.0 API) + + + + + + + + + + + +
    +
    org.owasp.dependencycheck.data.update.nvd
    +

    Class UpdateableNvdCve

    +
    +
    +
      +
    • java.lang.Object
    • +
    • +
        +
      • org.owasp.dependencycheck.data.update.nvd.UpdateableNvdCve
      • +
      +
    • +
    +
    + +
    +
    + +
    +
    +
      +
    • + +
        +
      • + + +

        Constructor Detail

        + + + +
          +
        • +

          UpdateableNvdCve

          +
          public UpdateableNvdCve()
          +
        • +
        +
      • +
      + +
        +
      • + + +

        Method Detail

        + + + +
          +
        • +

          getCollection

          +
          protected Map<String,NvdCveInfo> getCollection()
          +
          Returns the collection of NvdCveInfo objects. This method is mainly used for testing.
          +
          Returns:
          the collection of NvdCveInfo objects
          +
        • +
        + + + +
          +
        • +

          isUpdateNeeded

          +
          public boolean isUpdateNeeded()
          +
          Gets whether or not an update is needed.
          +
          Returns:
          true or false depending on whether an update is needed
          +
        • +
        + + + + + + + +
          +
        • +

          add

          +
          public void add(String id,
          +       String url,
          +       String oldUrl,
          +       boolean needsUpdate)
          +         throws MalformedURLException,
          +                DownloadFailedException
          +
          Adds a new entry of updateable information to the contained collection.
          +
          Parameters:
          id - the key for the item to be added
          url - the URL to download the item
          oldUrl - the URL for the old version of the item (the NVD CVE old schema still contains useful data we need).
          needsUpdate - whether or not the data needs to be updated
          +
          Throws:
          +
          MalformedURLException - thrown if the URL provided is invalid
          +
          DownloadFailedException - thrown if the download fails.
          +
        • +
        + + + +
          +
        • +

          clear

          +
          public void clear()
          +
          Clears the contained collection of NvdCveInfo entries.
          +
        • +
        + + + +
          +
        • +

          getTimeStamp

          +
          public long getTimeStamp(String key)
          +
          Returns the timestamp for the given entry.
          +
          Parameters:
          key - the key to lookup in the collection of NvdCveInfo items
          +
          Returns:
          the timestamp for the given entry
          +
        • +
        + + + +
          +
        • +

          iterator

          +
          public Iterator<NvdCveInfo> iterator()
          +

          + Returns an iterator for the NvdCveInfo contained.

          +

          + This method is not thread safe.

          +
          +
          Specified by:
          +
          iterator in interface Iterable<NvdCveInfo>
          +
          Returns:
          an NvdCveInfo Iterator
          +
        • +
        + + + +
          +
        • +

          hasNext

          +
          public boolean hasNext()
          +

          + Returns whether or not there is another item in the collection.

          +

          + This method is not thread safe.

          +
          +
          Specified by:
          +
          hasNext in interface Iterator<NvdCveInfo>
          +
          Returns:
          true or false depending on whether or not another item exists in the collection
          +
        • +
        + + + +
          +
        • +

          next

          +
          public NvdCveInfo next()
          +

          + Returns the next item in the collection.

          +

          + This method is not thread safe.

          +
          +
          Specified by:
          +
          next in interface Iterator<NvdCveInfo>
          +
          Returns:
          the next NvdCveInfo item in the collection
          +
        • +
        + + + +
          +
        • +

          remove

          +
          public void remove()
          +

          + Removes the current NvdCveInfo object from the collection.

          +

          + This method is not thread safe.

          +
          +
          Specified by:
          +
          remove in interface Iterator<NvdCveInfo>
          +
          +
        • +
        + + + +
          +
        • +

          get

          +
          public NvdCveInfo get(String key)
          +
          Returns the specified item from the collection.
          +
          Parameters:
          key - the key to lookup the return value
          +
          Returns:
          the NvdCveInfo object stored using the specified key
          +
        • +
        + + + + +
      • +
      +
    • +
    +
    +
    + + + + + +

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

    + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/class-use/DownloadTask.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/class-use/DownloadTask.html new file mode 100644 index 000000000..f1508114b --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/class-use/DownloadTask.html @@ -0,0 +1,161 @@ + + + + + + +Uses of Class org.owasp.dependencycheck.data.update.nvd.DownloadTask (Dependency-Check Core 1.3.0 API) + + + + + + + + + + +
    +

    Uses of Class
    org.owasp.dependencycheck.data.update.nvd.DownloadTask

    +
    +
    + +
    + + + + +

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

    + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/class-use/NvdCve12Handler.Element.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/class-use/NvdCve12Handler.Element.html new file mode 100644 index 000000000..9a5555ade --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/class-use/NvdCve12Handler.Element.html @@ -0,0 +1,117 @@ + + + + + + +Uses of Class org.owasp.dependencycheck.data.update.nvd.NvdCve12Handler.Element (Dependency-Check Core 1.3.0 API) + + + + + + + + + + +
    +

    Uses of Class
    org.owasp.dependencycheck.data.update.nvd.NvdCve12Handler.Element

    +
    +
    No usage of org.owasp.dependencycheck.data.update.nvd.NvdCve12Handler.Element
    + + + + +

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

    + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/class-use/NvdCve12Handler.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/class-use/NvdCve12Handler.html new file mode 100644 index 000000000..65b69718f --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/class-use/NvdCve12Handler.html @@ -0,0 +1,117 @@ + + + + + + +Uses of Class org.owasp.dependencycheck.data.update.nvd.NvdCve12Handler (Dependency-Check Core 1.3.0 API) + + + + + + + + + + +
    +

    Uses of Class
    org.owasp.dependencycheck.data.update.nvd.NvdCve12Handler

    +
    +
    No usage of org.owasp.dependencycheck.data.update.nvd.NvdCve12Handler
    + + + + +

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

    + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/class-use/NvdCve20Handler.Element.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/class-use/NvdCve20Handler.Element.html new file mode 100644 index 000000000..eabb3f698 --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/class-use/NvdCve20Handler.Element.html @@ -0,0 +1,117 @@ + + + + + + +Uses of Class org.owasp.dependencycheck.data.update.nvd.NvdCve20Handler.Element (Dependency-Check Core 1.3.0 API) + + + + + + + + + + +
    +

    Uses of Class
    org.owasp.dependencycheck.data.update.nvd.NvdCve20Handler.Element

    +
    +
    No usage of org.owasp.dependencycheck.data.update.nvd.NvdCve20Handler.Element
    + + + + +

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

    + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/class-use/NvdCve20Handler.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/class-use/NvdCve20Handler.html new file mode 100644 index 000000000..7b51544fd --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/class-use/NvdCve20Handler.html @@ -0,0 +1,117 @@ + + + + + + +Uses of Class org.owasp.dependencycheck.data.update.nvd.NvdCve20Handler (Dependency-Check Core 1.3.0 API) + + + + + + + + + + +
    +

    Uses of Class
    org.owasp.dependencycheck.data.update.nvd.NvdCve20Handler

    +
    +
    No usage of org.owasp.dependencycheck.data.update.nvd.NvdCve20Handler
    + + + + +

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

    + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/class-use/NvdCveInfo.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/class-use/NvdCveInfo.html new file mode 100644 index 000000000..ebb9a72e0 --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/class-use/NvdCveInfo.html @@ -0,0 +1,253 @@ + + + + + + +Uses of Class org.owasp.dependencycheck.data.update.nvd.NvdCveInfo (Dependency-Check Core 1.3.0 API) + + + + + + + + + + +
    +

    Uses of Class
    org.owasp.dependencycheck.data.update.nvd.NvdCveInfo

    +
    +
    + +
    + + + + +

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

    + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/class-use/ProcessTask.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/class-use/ProcessTask.html new file mode 100644 index 000000000..19a07b24e --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/class-use/ProcessTask.html @@ -0,0 +1,174 @@ + + + + + + +Uses of Class org.owasp.dependencycheck.data.update.nvd.ProcessTask (Dependency-Check Core 1.3.0 API) + + + + + + + + + + +
    +

    Uses of Class
    org.owasp.dependencycheck.data.update.nvd.ProcessTask

    +
    +
    + +
    + + + + +

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

    + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/class-use/UpdateableNvdCve.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/class-use/UpdateableNvdCve.html new file mode 100644 index 000000000..2a54ac2ec --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/class-use/UpdateableNvdCve.html @@ -0,0 +1,178 @@ + + + + + + +Uses of Class org.owasp.dependencycheck.data.update.nvd.UpdateableNvdCve (Dependency-Check Core 1.3.0 API) + + + + + + + + + + +
    +

    Uses of Class
    org.owasp.dependencycheck.data.update.nvd.UpdateableNvdCve

    +
    +
    + +
    + + + + +

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

    + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/package-frame.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/package-frame.html new file mode 100644 index 000000000..fab5035c5 --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/package-frame.html @@ -0,0 +1,27 @@ + + + + + + +org.owasp.dependencycheck.data.update.nvd (Dependency-Check Core 1.3.0 API) + + + + +

    org.owasp.dependencycheck.data.update.nvd

    + + + 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 new file mode 100644 index 000000000..19b2131ae --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/package-summary.html @@ -0,0 +1,188 @@ + + + + + + +org.owasp.dependencycheck.data.update.nvd (Dependency-Check Core 1.3.0 API) + + + + + + + +
    + + + + + +
    + + +
    +

    Package org.owasp.dependencycheck.data.update.nvd

    +
    +
    Contains classes used to download, parse, and load the NVD CVE data from NIST into the local database.

    +
    +

    See: Description

    +
    +
    +
      +
    • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Class Summary 
      ClassDescription
      DownloadTask +
      A callable object to download two files.
      +
      NvdCve12Handler +
      A SAX Handler that will parse the NVD CVE XML (schema version 1.2).
      +
      NvdCve12Handler.Element +
      A simple class to maintain information about the current element while parsing the NVD CVE XML.
      +
      NvdCve20Handler +
      A SAX Handler that will parse the NVD CVE XML (schema version 2.0).
      +
      NvdCve20Handler.Element +
      A simple class to maintain information about the current element while parsing the NVD CVE XML.
      +
      NvdCveInfo +
      A pojo that contains the Url and timestamp of the current NvdCve XML files.
      +
      ProcessTask +
      A callable task that will process a given set of NVD CVE xml files and update the Cve Database accordingly.
      +
      UpdateableNvdCve +
      Contains a collection of updateable NvdCveInfo objects.
      +
      +
    • +
    + + + +

    Package org.owasp.dependencycheck.data.update.nvd Description

    +
    Contains classes used to download, parse, and load the NVD CVE data from NIST into the local database.

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

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

    + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/package-tree.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/package-tree.html new file mode 100644 index 000000000..13c778f8c --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/package-tree.html @@ -0,0 +1,141 @@ + + + + + + +org.owasp.dependencycheck.data.update.nvd Class Hierarchy (Dependency-Check Core 1.3.0 API) + + + + + + + +
    + + + + + +
    + + +
    +

    Hierarchy For Package org.owasp.dependencycheck.data.update.nvd

    +Package Hierarchies: + +
    +
    +

    Class Hierarchy

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

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

    + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/package-use.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/package-use.html new file mode 100644 index 000000000..a16c761eb --- /dev/null +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/nvd/package-use.html @@ -0,0 +1,212 @@ + + + + + + +Uses of Package org.owasp.dependencycheck.data.update.nvd (Dependency-Check Core 1.3.0 API) + + + + + + + + + + +
    +

    Uses of Package
    org.owasp.dependencycheck.data.update.nvd

    +
    +
    + +
    + + + + +

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

    + + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/package-frame.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/package-frame.html index 7e91ecc67..53767b22e 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/package-frame.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/data/update/package-frame.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.data.update (Dependency-Check Core 1.2.11 API) - +org.owasp.dependencycheck.data.update (Dependency-Check Core 1.3.0 API) + @@ -17,11 +17,10 @@

    Classes

    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 0f4266d29..9dd529428 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,16 +2,16 @@ - + -org.owasp.dependencycheck.data.update (Dependency-Check Core 1.2.11 API) - +org.owasp.dependencycheck.data.update (Dependency-Check Core 1.3.0 API) + @@ -38,7 +38,7 @@ + +FileFilterBuilder +
    + Utility class for building useful FileFilter instances for + AbstractFileTypeAnalyzer implementations.
    + +
  • diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/License.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/License.html index 0ab2e49f6..dbe88449c 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/License.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/License.html @@ -2,16 +2,16 @@ - + -License (Dependency-Check Core 1.2.11 API) - +License (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/Model.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/Model.html index 757e14c9c..2d716e0fc 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/Model.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/Model.html @@ -2,16 +2,16 @@ - + -Model (Dependency-Check Core 1.2.11 API) - +Model (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/PomHandler.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/PomHandler.html index 81ce2f3db..d5fcca261 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/PomHandler.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/PomHandler.html @@ -2,16 +2,16 @@ - + -PomHandler (Dependency-Check Core 1.2.11 API) - +PomHandler (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/PomParseException.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/PomParseException.html index d33689a7e..17e931b34 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/PomParseException.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/PomParseException.html @@ -2,16 +2,16 @@ - + -PomParseException (Dependency-Check Core 1.2.11 API) - +PomParseException (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/PomParser.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/PomParser.html index 3c331ba4a..66ef6c92b 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/PomParser.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/PomParser.html @@ -2,16 +2,16 @@ - + -PomParser (Dependency-Check Core 1.2.11 API) - +PomParser (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/PomUtils.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/PomUtils.html index 3bf0906f5..44881965b 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/PomUtils.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/PomUtils.html @@ -2,16 +2,16 @@ - + -PomUtils (Dependency-Check Core 1.2.11 API) - +PomUtils (Dependency-Check Core 1.3.0 API) + @@ -173,8 +173,7 @@ extends Parameters:
    file - the pom.xml file
    Returns:
    returns a
    Throws:
    -
    AnalysisException - is thrown if there is an exception extracting or parsing the POM - org.owasp.dependencycheck.jaxb.pom.generated.Model object
    +
    AnalysisException - is thrown if there is an exception extracting or parsing the POM Model object
    @@ -190,8 +189,7 @@ extends Parameters:
    path - the path to the pom.xml file within the jar file
    jar - the jar file to extract the pom from
    Returns:
    returns a
    Throws:
    -
    AnalysisException - is thrown if there is an exception extracting or parsing the POM - org.owasp.dependencycheck.jaxb.pom.generated.Model object
    +
    AnalysisException - is thrown if there is an exception extracting or parsing the POM Model object
    diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/class-use/License.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/class-use/License.html index 4e11a734a..6d44fc48c 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/class-use/License.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/class-use/License.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.xml.pom.License (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.xml.pom.License (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/class-use/Model.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/class-use/Model.html index a37b140c8..4d7ed5013 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/class-use/Model.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/class-use/Model.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.xml.pom.Model (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.xml.pom.Model (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/class-use/PomHandler.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/class-use/PomHandler.html index da50e6bd0..d25fb0709 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/class-use/PomHandler.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/class-use/PomHandler.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.xml.pom.PomHandler (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.xml.pom.PomHandler (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/class-use/PomParseException.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/class-use/PomParseException.html index 8780ccf87..036008417 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/class-use/PomParseException.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/class-use/PomParseException.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.xml.pom.PomParseException (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.xml.pom.PomParseException (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/class-use/PomParser.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/class-use/PomParser.html index 1012dfad2..6a3315c3e 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/class-use/PomParser.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/class-use/PomParser.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.xml.pom.PomParser (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.xml.pom.PomParser (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/class-use/PomUtils.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/class-use/PomUtils.html index c59cd7a7e..d0099b665 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/class-use/PomUtils.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/class-use/PomUtils.html @@ -2,16 +2,16 @@ - + -Uses of Class org.owasp.dependencycheck.xml.pom.PomUtils (Dependency-Check Core 1.2.11 API) - +Uses of Class org.owasp.dependencycheck.xml.pom.PomUtils (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/package-frame.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/package-frame.html index 3ee23539d..ecbc60282 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/package-frame.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/package-frame.html @@ -2,10 +2,10 @@ - + -org.owasp.dependencycheck.xml.pom (Dependency-Check Core 1.2.11 API) - +org.owasp.dependencycheck.xml.pom (Dependency-Check Core 1.3.0 API) + 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 27f154ff2..0af8dc960 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,16 +2,16 @@ - + -org.owasp.dependencycheck.xml.pom (Dependency-Check Core 1.2.11 API) - +org.owasp.dependencycheck.xml.pom (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/package-tree.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/package-tree.html index 8bd1a737b..da84a18a5 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/package-tree.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/package-tree.html @@ -2,16 +2,16 @@ - + -org.owasp.dependencycheck.xml.pom Class Hierarchy (Dependency-Check Core 1.2.11 API) - +org.owasp.dependencycheck.xml.pom Class Hierarchy (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/package-use.html b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/package-use.html index 7a1529ee1..fba76f426 100644 --- a/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/package-use.html +++ b/dependency-check-core/apidocs/org/owasp/dependencycheck/xml/pom/package-use.html @@ -2,16 +2,16 @@ - + -Uses of Package org.owasp.dependencycheck.xml.pom (Dependency-Check Core 1.2.11 API) - +Uses of Package org.owasp.dependencycheck.xml.pom (Dependency-Check Core 1.3.0 API) + diff --git a/dependency-check-core/apidocs/overview-frame.html b/dependency-check-core/apidocs/overview-frame.html index 282d34654..7493b2de7 100644 --- a/dependency-check-core/apidocs/overview-frame.html +++ b/dependency-check-core/apidocs/overview-frame.html @@ -2,10 +2,10 @@ - + -Overview List (Dependency-Check Core 1.2.11 API) - +Overview List (Dependency-Check Core 1.3.0 API) + @@ -25,9 +25,9 @@
  • org.owasp.dependencycheck.data.nuget
  • org.owasp.dependencycheck.data.nvdcve
  • org.owasp.dependencycheck.data.update
  • +
  • org.owasp.dependencycheck.data.update.cpe
  • org.owasp.dependencycheck.data.update.exception
  • -
  • org.owasp.dependencycheck.data.update.task
  • -
  • org.owasp.dependencycheck.data.update.xml
  • +
  • org.owasp.dependencycheck.data.update.nvd
  • org.owasp.dependencycheck.dependency
  • org.owasp.dependencycheck.exception
  • org.owasp.dependencycheck.reporting
  • diff --git a/dependency-check-core/apidocs/overview-summary.html b/dependency-check-core/apidocs/overview-summary.html index c407071f9..42989d5bd 100644 --- a/dependency-check-core/apidocs/overview-summary.html +++ b/dependency-check-core/apidocs/overview-summary.html @@ -2,16 +2,16 @@ - + -Overview (Dependency-Check Core 1.2.11 API) - +Overview (Dependency-Check Core 1.3.0 API) + @@ -64,7 +64,7 @@
    -

    Dependency-Check Core 1.2.11 API

    +

    Dependency-Check Core 1.3.0 API

    @@ -155,23 +155,23 @@ + + + + - - - - - + diff --git a/dependency-check-core/apidocs/overview-tree.html b/dependency-check-core/apidocs/overview-tree.html index d79762fb8..363d3c497 100644 --- a/dependency-check-core/apidocs/overview-tree.html +++ b/dependency-check-core/apidocs/overview-tree.html @@ -2,16 +2,16 @@ - + -Class Hierarchy (Dependency-Check Core 1.2.11 API) - +Class Hierarchy (Dependency-Check Core 1.3.0 API) + @@ -79,9 +79,9 @@
  • org.owasp.dependencycheck.data.nuget,
  • org.owasp.dependencycheck.data.nvdcve,
  • org.owasp.dependencycheck.data.update,
  • +
  • org.owasp.dependencycheck.data.update.cpe,
  • org.owasp.dependencycheck.data.update.exception,
  • -
  • org.owasp.dependencycheck.data.update.task,
  • -
  • org.owasp.dependencycheck.data.update.xml,
  • +
  • org.owasp.dependencycheck.data.update.nvd,
  • org.owasp.dependencycheck.dependency,
  • org.owasp.dependencycheck.exception,
  • org.owasp.dependencycheck.reporting,
  • @@ -101,11 +101,13 @@ @@ -156,9 +158,17 @@ +
  • org.owasp.dependencycheck.data.update.BaseUpdater + +
  • org.owasp.dependencycheck.data.central.CentralSearch
  • org.owasp.dependencycheck.data.nvdcve.ConnectionFactory
  • +
  • org.owasp.dependencycheck.data.update.cpe.Cpe
  • org.owasp.dependencycheck.analyzer.CPEAnalyzer (implements org.owasp.dependencycheck.analyzer.Analyzer)
  • +
  • org.owasp.dependencycheck.data.update.cpe.CPEHandler.Element
  • org.owasp.dependencycheck.data.cpe.CpeMemoryIndex
  • org.owasp.dependencycheck.data.nvdcve.CveDB
  • org.owasp.dependencycheck.data.cwe.CweDB
  • @@ -167,9 +177,10 @@
  • org.owasp.dependencycheck.utils.DBUtils
  • org.xml.sax.helpers.DefaultHandler (implements org.xml.sax.ContentHandler, org.xml.sax.DTDHandler, org.xml.sax.EntityResolver, org.xml.sax.ErrorHandler) @@ -178,15 +189,16 @@
  • org.owasp.dependencycheck.agent.DependencyCheckScanAgent
  • org.owasp.dependencycheck.utils.DependencyVersion (implements java.lang.Comparable<T>, java.lang.Iterable<T>)
  • org.owasp.dependencycheck.utils.DependencyVersionUtil
  • -
  • org.owasp.dependencycheck.data.update.task.DownloadTask (implements java.util.concurrent.Callable<V>)
  • +
  • org.owasp.dependencycheck.data.update.nvd.DownloadTask (implements java.util.concurrent.Callable<V>)
  • org.owasp.dependencycheck.data.nvdcve.DriverLoader
  • -
  • org.owasp.dependencycheck.Engine
  • +
  • org.owasp.dependencycheck.Engine (implements java.io.FileFilter)
  • org.owasp.dependencycheck.data.update.EngineVersionCheck (implements org.owasp.dependencycheck.data.update.CachedWebDataSource)
  • org.owasp.dependencycheck.reporting.EscapeTool
  • org.owasp.dependencycheck.dependency.Evidence (implements java.lang.Comparable<T>, java.io.Serializable)
  • org.owasp.dependencycheck.dependency.EvidenceCollection (implements java.lang.Iterable<T>, java.io.Serializable)
  • org.owasp.dependencycheck.utils.ExtractionUtil
  • org.owasp.dependencycheck.data.cpe.Fields
  • +
  • org.owasp.dependencycheck.utils.FileFilterBuilder
  • org.owasp.dependencycheck.utils.Filter<T>
  • org.owasp.dependencycheck.dependency.Identifier (implements java.lang.Comparable<T>, java.io.Serializable)
  • org.owasp.dependencycheck.data.cpe.IndexEntry (implements java.io.Serializable) @@ -210,15 +222,14 @@
  • org.owasp.dependencycheck.xml.pom.Model
  • org.owasp.dependencycheck.data.nexus.NexusSearch
  • org.owasp.dependencycheck.data.nuget.NugetPackage
  • -
  • org.owasp.dependencycheck.data.update.xml.NvdCve12Handler.Element
  • -
  • org.owasp.dependencycheck.data.update.xml.NvdCve20Handler.Element
  • +
  • org.owasp.dependencycheck.data.update.nvd.NvdCve12Handler.Element
  • +
  • org.owasp.dependencycheck.data.update.nvd.NvdCve20Handler.Element
  • org.owasp.dependencycheck.analyzer.NvdCveAnalyzer (implements org.owasp.dependencycheck.analyzer.Analyzer)
  • -
  • org.owasp.dependencycheck.data.update.NvdCveInfo
  • -
  • org.owasp.dependencycheck.data.update.NvdCveUpdater (implements org.owasp.dependencycheck.data.update.CachedWebDataSource)
  • +
  • org.owasp.dependencycheck.data.update.nvd.NvdCveInfo
  • org.owasp.dependencycheck.utils.Pair<L,R>
  • org.owasp.dependencycheck.xml.pom.PomParser
  • org.owasp.dependencycheck.xml.pom.PomUtils
  • -
  • org.owasp.dependencycheck.data.update.task.ProcessTask (implements java.util.concurrent.Callable<V>)
  • +
  • org.owasp.dependencycheck.data.update.nvd.ProcessTask (implements java.util.concurrent.Callable<V>)
  • org.owasp.dependencycheck.suppression.PropertyType
  • org.owasp.dependencycheck.dependency.Reference (implements java.lang.Comparable<T>, java.io.Serializable)
  • org.owasp.dependencycheck.reporting.ReportGenerator
  • @@ -235,7 +246,6 @@ -
  • org.owasp.dependencycheck.data.update.StandardUpdate
  • org.owasp.dependencycheck.suppression.SuppressionErrorHandler (implements org.xml.sax.ErrorHandler)
  • org.owasp.dependencycheck.suppression.SuppressionParser
  • org.owasp.dependencycheck.suppression.SuppressionRule
  • @@ -263,7 +273,7 @@ -
  • org.owasp.dependencycheck.data.update.UpdateableNvdCve (implements java.lang.Iterable<T>, java.util.Iterator<E>)
  • +
  • org.owasp.dependencycheck.data.update.nvd.UpdateableNvdCve (implements java.lang.Iterable<T>, java.util.Iterator<E>)
  • org.owasp.dependencycheck.data.update.UpdateService
  • org.owasp.dependencycheck.utils.UrlStringUtils
  • org.owasp.dependencycheck.reporting.VelocityLoggerRedirect (implements org.apache.velocity.runtime.log.LogChute)
  • @@ -277,10 +287,15 @@

    Enum Hierarchy

    diff --git a/dependency-check-core/apidocs/package-list b/dependency-check-core/apidocs/package-list index 5aaee1d78..4e1863840 100644 --- a/dependency-check-core/apidocs/package-list +++ b/dependency-check-core/apidocs/package-list @@ -10,9 +10,9 @@ org.owasp.dependencycheck.data.nexus org.owasp.dependencycheck.data.nuget org.owasp.dependencycheck.data.nvdcve org.owasp.dependencycheck.data.update +org.owasp.dependencycheck.data.update.cpe org.owasp.dependencycheck.data.update.exception -org.owasp.dependencycheck.data.update.task -org.owasp.dependencycheck.data.update.xml +org.owasp.dependencycheck.data.update.nvd org.owasp.dependencycheck.dependency org.owasp.dependencycheck.exception org.owasp.dependencycheck.reporting diff --git a/dependency-check-core/apidocs/serialized-form.html b/dependency-check-core/apidocs/serialized-form.html index a9ca43f9d..47752d136 100644 --- a/dependency-check-core/apidocs/serialized-form.html +++ b/dependency-check-core/apidocs/serialized-form.html @@ -2,16 +2,16 @@ - + -Serialized Form (Dependency-Check Core 1.2.11 API) - +Serialized Form (Dependency-Check Core 1.3.0 API) + @@ -232,11 +232,6 @@
    The file name of the dependency.
  • -

    fileExtension

    -
    String fileExtension
    -
    The file extension of the dependency.
    -
  • -
  • md5sum

    String md5sum
    The md5 hash of the dependency.
    @@ -577,9 +572,9 @@
    The product version number.
  • -

    revision

    -
    String revision
    -
    The product revision version.
    +

    update

    +
    String update
    +
    The product update version.
  • edition

    diff --git a/dependency-check-core/checkstyle.html b/dependency-check-core/checkstyle.html index d2c8729dd..f8a855f80 100644 --- a/dependency-check-core/checkstyle.html +++ b/dependency-check-core/checkstyle.html @@ -1,13 +1,13 @@ - + dependency-check-core - Checkstyle Results @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -175,16 +175,16 @@
  • - + - PMD + CPD Report
  • - + - CPD + PMD Report
  • @@ -249,10 +249,10 @@
  • - + -
    org.owasp.dependencycheck.data.update.cpe +
    Contains classes used to parse the CPE XML file from NIST.

    + + These classes are not used as they add no value over the existing CPE data contained within the CVE data from the NVD.
    +
    org.owasp.dependencycheck.data.update.exception
    A collection of exception classes used within the application.
    org.owasp.dependencycheck.data.update.task -
    A collection of callable/runnable tasks used to speed up the update process.
    -
    org.owasp.dependencycheck.data.update.xmlorg.owasp.dependencycheck.data.update.nvd -
    Contains classes used to parse the NVD CVE XML file.

    - - The basic use is that the Importer is called to import an NVD CVE file.
    +
    Contains classes used to download, parse, and load the NVD CVE data from NIST into the local database.

    Warnings Warnings Errors Errors
    204197 0 06
    +21

    Details

    @@ -276,13 +276,13 @@ Errors Inner assignments should be avoided. -124 +133 Errors Must have at least one statement. -239
    +249
    -

    org/owasp/dependencycheck/analyzer/JavaScriptAnalyzer.java

    +

    org/owasp/dependencycheck/analyzer/CMakeAnalyzer.java

    @@ -290,12 +290,82 @@ - - + + - -
    ViolationLine
    ErrorsVariable 'file' should be declared final.114
    Missing a Javadoc comment.65
    ErrorsVariable 'sb' should be declared final.116
    +Missing a Javadoc comment. +70 + +Errors +Missing a Javadoc comment. +175 + +Errors +Assignment of parameter 'dependency' is not allowed. +194 +
    +

    org/owasp/dependencycheck/analyzer/OpenSSLAnalyzer.java

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ViolationMessageLine
    ErrorsMissing a Javadoc comment.41
    ErrorsMissing a Javadoc comment.51
    ErrorsMissing a Javadoc comment.54
    ErrorsMissing a Javadoc comment.55
    ErrorsMissing a Javadoc comment.56
    ErrorsMissing a Javadoc comment.57
    ErrorsMissing a Javadoc comment.58
    ErrorsMissing a Javadoc comment.59
    ErrorsMissing a Javadoc comment.60
    ErrorsMissing a Javadoc comment.61
    ErrorsMissing a Javadoc comment.62
    +
    +

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

    + + + + + + + + +
    ViolationMessageLine
    ErrorsVariable 'ids' should be declared final.493

    org/owasp/dependencycheck/dependency/Dependency.java

    @@ -305,8 +375,12 @@ - -
    Line
    ErrorsTotal number of methods is 56 (max allowed is 40).43
    +Total number of methods is 54 (max allowed is 40). +44 + +Errors +Array should contain trailing comma. +739 diff --git a/dependency-check-core/checkstyle.rss b/dependency-check-core/checkstyle.rss index 6005de85b..6da76edc9 100644 --- a/dependency-check-core/checkstyle.rss +++ b/dependency-check-core/checkstyle.rss @@ -25,8 +25,8 @@ under the License. en-us ©2012 - 2015 OWASP - File: 204, - Errors: 6, + <title>File: 197, + Errors: 21, Warnings: 0, Infos: 0 @@ -45,20 +45,6 @@ under the License. - - org/owasp/dependencycheck/data/update/StandardUpdate.java - - - 0 - - - 0 - - - 0 - - - org/owasp/dependencycheck/analyzer/exception/AnalysisException.java @@ -181,7 +167,21 @@ under the License. 0 - 1 + 2 + + + + + dependency-check-gradle/src/main/resources/META-INF/gradle-plugins/dependency-check.properties + + + 0 + + + 0 + + + 0 @@ -239,6 +239,20 @@ under the License. 0 + + + + org/owasp/dependencycheck/data/update/cpe/package-info.java + + + 0 + + + 0 + + + 0 + @@ -295,20 +309,6 @@ under the License. 0 - - - - dependency-check-maven/target/generated-classes/cobertura/log.properties - - - 0 - - - 0 - - - 0 - @@ -603,20 +603,6 @@ under the License. 0 - - - - dependency-check-ant/target/classes/log.properties - - - 0 - - - 0 - - - 0 - @@ -631,20 +617,6 @@ under the License. 0 - - - - org/owasp/dependencycheck/data/update/task/DownloadTask.java - - - 0 - - - 0 - - - 0 - @@ -659,20 +631,6 @@ under the License. 0 - - - - dependency-check-utils/src/test/resources/dependencycheck.properties - - - 0 - - - 0 - - - 0 - @@ -690,7 +648,7 @@ under the License. - dependency-check-cli/target/generated-classes/cobertura/log.properties + dependency-check-utils/src/test/resources/dependencycheck.properties 0 @@ -715,20 +673,6 @@ under the License. 0 - - - - dependency-check-core/target/generated-classes/cobertura/dependencycheck-resources.properties - - - 0 - - - 0 - - - 0 - @@ -771,6 +715,20 @@ under the License. 0 + + + + org/owasp/dependencycheck/data/update/cpe/Cpe.java + + + 0 + + + 0 + + + 0 + @@ -799,20 +757,6 @@ under the License. 0 - - - - dependency-check-core/target/test-classes/log.properties - - - 0 - - - 0 - - - 0 - @@ -841,20 +785,6 @@ under the License. 0 - - - - dependency-check-cli/src/main/resources/log.properties - - - 0 - - - 0 - - - 0 - @@ -897,6 +827,34 @@ under the License. 0 + + + + dependency-check-gradle/.gradle/2.3/taskArtifacts/cache.properties + + + 0 + + + 0 + + + 0 + + + + + org/owasp/dependencycheck/data/update/nvd/package-info.java + + + 0 + + + 0 + + + 0 + @@ -911,6 +869,20 @@ under the License. 0 + + + + org/owasp/dependencycheck/analyzer/OpenSSLAnalyzer.java + + + 0 + + + 0 + + + 11 + @@ -1023,6 +995,20 @@ under the License. 0 + + + + org/owasp/dependencycheck/data/update/nvd/ProcessTask.java + + + 0 + + + 0 + + + 0 + @@ -1051,6 +1037,20 @@ under the License. 0 + + + + org/owasp/dependencycheck/data/update/CpeUpdater.java + + + 0 + + + 0 + + + 0 + @@ -1091,7 +1091,7 @@ under the License. 0 - 0 + 1 @@ -1138,7 +1138,7 @@ under the License. - dependency-check-ant/target/generated-classes/cobertura/log.properties + org/owasp/dependencycheck/data/update/nvd/UpdateableNvdCve.java 0 @@ -1303,20 +1303,6 @@ under the License. 0 - - - - org/owasp/dependencycheck/data/update/task/ProcessTask.java - - - 0 - - - 0 - - - 0 - @@ -1373,48 +1359,6 @@ under the License. 0 - - - - org/owasp/dependencycheck/analyzer/JavaScriptAnalyzer.java - - - 0 - - - 0 - - - 2 - - - - - dependency-check-maven/src/main/resources/log.properties - - - 0 - - - 0 - - - 0 - - - - - org/owasp/dependencycheck/data/update/xml/package-info.java - - - 0 - - - 0 - - - 0 - @@ -1485,20 +1429,6 @@ under the License. 0 - - - - dependency-check-maven/target/classes/log.properties - - - 0 - - - 0 - - - 0 - @@ -1583,20 +1513,6 @@ under the License. 0 - - - - dependency-check-ant/src/main/resources/log.properties - - - 0 - - - 0 - - - 0 - @@ -1639,20 +1555,6 @@ under the License. 0 - - - - dependency-check-core/src/test/resources/log.properties - - - 0 - - - 0 - - - 0 - @@ -1667,20 +1569,6 @@ under the License. 0 - - - - dependency-check-core/src/main/resources/dependencycheck-resources.properties - - - 0 - - - 0 - - - 0 - @@ -1779,6 +1667,20 @@ under the License. 0 + + + + org/owasp/dependencycheck/data/update/nvd/NvdCveInfo.java + + + 0 + + + 0 + + + 0 + @@ -1810,7 +1712,7 @@ under the License. - org/owasp/dependencycheck/data/update/xml/NvdCve12Handler.java + org/owasp/dependencycheck/analyzer/AutoconfAnalyzer.java 0 @@ -1863,20 +1765,6 @@ under the License. 0 - - - - dependencycheck-resources.properties - - - 0 - - - 0 - - - 0 - @@ -1919,20 +1807,6 @@ under the License. 0 - - - - org/owasp/dependencycheck/data/update/xml/NvdCve20Handler.java - - - 0 - - - 0 - - - 0 - @@ -2048,7 +1922,7 @@ under the License. - dependency-check-maven/target/maven-plugin-plugin-sources/org.apache.maven.plugins/maven-site-plugin/3.4/sources/site-plugin_tr.properties + org/owasp/dependencycheck/analyzer/FalsePositiveAnalyzer.java 0 @@ -2062,7 +1936,7 @@ under the License. - org/owasp/dependencycheck/analyzer/FalsePositiveAnalyzer.java + dependency-check-maven/target/maven-plugin-plugin-sources/org.apache.maven.plugins/maven-site-plugin/3.4/sources/site-plugin_tr.properties 0 @@ -2115,6 +1989,20 @@ under the License. 0 + + + + org/owasp/dependencycheck/data/update/cpe/CPEHandler.java + + + 0 + + + 0 + + + 0 + @@ -2227,20 +2115,6 @@ under the License. 0 - - - - org/owasp/dependencycheck/data/update/UpdateableNvdCve.java - - - 0 - - - 0 - - - 0 - @@ -2283,6 +2157,20 @@ under the License. 0 + + + + org/owasp/dependencycheck/data/update/nvd/DownloadTask.java + + + 0 + + + 0 + + + 0 + @@ -2437,6 +2325,20 @@ under the License. 0 + + + + org/owasp/dependencycheck/data/update/nvd/NvdCve12Handler.java + + + 0 + + + 0 + + + 0 + @@ -2552,7 +2454,7 @@ under the License. - org/owasp/dependencycheck/data/update/task/package-info.java + org/owasp/dependencycheck/data/update/nvd/NvdCve20Handler.java 0 @@ -2661,20 +2563,6 @@ under the License. 0 - - - - dependency-check-cli/target/classes/log.properties - - - 0 - - - 0 - - - 0 - @@ -2703,6 +2591,20 @@ under the License. 1 + + + + org/owasp/dependencycheck/data/update/BaseUpdater.java + + + 0 + + + 0 + + + 0 + @@ -2720,7 +2622,7 @@ under the License. - org/owasp/dependencycheck/data/update/NvdCveInfo.java + org/owasp/dependencycheck/analyzer/CMakeAnalyzer.java 0 @@ -2729,21 +2631,7 @@ under the License. 0 - 0 - - - - - dependency-check-core/target/classes/dependencycheck-resources.properties - - - 0 - - - 0 - - - 0 + 4 @@ -2885,6 +2773,20 @@ under the License. 0 + + + + org/owasp/dependencycheck/utils/FileFilterBuilder.java + + + 0 + + + 0 + + + 0 + diff --git a/dependency-check-core/cobertura/frame-packages.html b/dependency-check-core/cobertura/frame-packages.html index 4b41888c1..e74b254bc 100644 --- a/dependency-check-core/cobertura/frame-packages.html +++ b/dependency-check-core/cobertura/frame-packages.html @@ -49,13 +49,13 @@ org.owasp.dependencycheck.data.update +org.owasp.dependencycheck.data.update.cpe + + org.owasp.dependencycheck.data.update.exception -org.owasp.dependencycheck.data.update.task - - -org.owasp.dependencycheck.data.update.xml +org.owasp.dependencycheck.data.update.nvd org.owasp.dependencycheck.dependency diff --git a/dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.analyzer.html b/dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.analyzer.html index 3b383e2b9..7536cdf1a 100644 --- a/dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.analyzer.html +++ b/dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.analyzer.html @@ -18,7 +18,7 @@ org.owasp.dependencycheck.analyzer AbstractAnalyzer (100%) -AbstractFileTypeAnalyzer (74%) +AbstractFileTypeAnalyzer (82%) AbstractSuppressionAnalyzer (80%) @@ -39,16 +39,22 @@ org.owasp.dependencycheck.analyzer AssemblyAnalyzer (67%) -CPEAnalyzer (72%) +AutoconfAnalyzer (92%) -CentralAnalyzer (25%) +CMakeAnalyzer (93%) + + +CPEAnalyzer (74%) + + +CentralAnalyzer (27%) CpeSuppressionAnalyzer (90%) -DependencyBundlingAnalyzer (41%) +DependencyBundlingAnalyzer (42%) FalsePositiveAnalyzer (49%) @@ -60,16 +66,13 @@ org.owasp.dependencycheck.analyzer FileTypeAnalyzer (N/A) -HintAnalyzer (78%) +HintAnalyzer (75%) -JarAnalyzer (62%) +JarAnalyzer (63%) -JavaScriptAnalyzer (29%) - - -NexusAnalyzer (18%) +NexusAnalyzer (20%) NuspecAnalyzer (22%) @@ -78,6 +81,9 @@ org.owasp.dependencycheck.analyzer NvdCveAnalyzer (68%) +OpenSSLAnalyzer (91%) + + PythonDistributionAnalyzer (86%) diff --git a/dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.data.central.html b/dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.data.central.html index ff7613482..de929bbc4 100644 --- a/dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.data.central.html +++ b/dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.data.central.html @@ -15,7 +15,7 @@ org.owasp.dependencycheck.data.central - +
    CentralSearch (83%)CentralSearch (85%)
    diff --git a/dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.data.cpe.html b/dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.data.cpe.html index 61022bef1..4f8990e90 100644 --- a/dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.data.cpe.html +++ b/dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.data.cpe.html @@ -21,7 +21,7 @@ org.owasp.dependencycheck.data.cpe Fields (0%) -IndexEntry (66%) +IndexEntry (63%) IndexException (0%) diff --git a/dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.data.nvdcve.html b/dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.data.nvdcve.html index 04d0b4849..05381e881 100644 --- a/dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.data.nvdcve.html +++ b/dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.data.nvdcve.html @@ -15,25 +15,25 @@ org.owasp.dependencycheck.data.nvdcve - + - + - + - + diff --git a/dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.data.update.cpe.html b/dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.data.update.cpe.html new file mode 100644 index 000000000..f4979fb07 --- /dev/null +++ b/dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.data.update.cpe.html @@ -0,0 +1,26 @@ + + + + +Coverage Report Classes + + + +
    +org.owasp.dependencycheck.data.update.cpe +
    +
     
    +
    Classes
    +
    ConnectionFactory (42%)ConnectionFactory (33%)
    CorruptDatabaseException (0%)
    CveDB (45%)CveDB (44%)
    DatabaseException (0%)
    DatabaseProperties (20%)DatabaseProperties (22%)
    DriverLoadException (33%)
    DriverLoader (56%)DriverLoader (59%)
    DriverShim (17%)
    + + + + + + + + +
    CPEHandler (0%)
    Cpe (0%)
    + + diff --git a/dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.data.update.html b/dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.data.update.html index 533df9a78..d6da87dd1 100644 --- a/dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.data.update.html +++ b/dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.data.update.html @@ -15,26 +15,23 @@ org.owasp.dependencycheck.data.update + + + - + - + - - - - - -
    BaseUpdater (70%)
    CachedWebDataSource (N/A)
    EngineVersionCheck (47%)CpeUpdater (0%)
    NvdCveInfo (100%)EngineVersionCheck (51%)
    NvdCveUpdater (0%)
    StandardUpdate (0%)
    UpdateService (0%)
    UpdateableNvdCve (93%)
    diff --git a/dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.data.update.nvd.html b/dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.data.update.nvd.html new file mode 100644 index 000000000..5c6fa6cbe --- /dev/null +++ b/dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.data.update.nvd.html @@ -0,0 +1,38 @@ + + + + +Coverage Report Classes + + + +
    +org.owasp.dependencycheck.data.update.nvd +
    +
     
    +
    Classes
    + + + + + + + + + + + + + + + + + + + + + +
    DownloadTask (59%)
    NvdCve12Handler (93%)
    NvdCve20Handler (81%)
    NvdCveInfo (100%)
    ProcessTask (0%)
    UpdateableNvdCve (93%)
    + + diff --git a/dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.dependency.html b/dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.dependency.html index 74b82f35d..eb9536c82 100644 --- a/dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.dependency.html +++ b/dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.dependency.html @@ -18,10 +18,10 @@ org.owasp.dependencycheck.dependency Confidence (100%) -Dependency (60%) +Dependency (66%) -Evidence (65%) +Evidence (67%) EvidenceCollection (73%) diff --git a/dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.html b/dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.html index 0a4463e7e..08d5226ba 100644 --- a/dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.html +++ b/dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.html @@ -15,7 +15,7 @@ org.owasp.dependencycheck - +
    Engine (53%)Engine (52%)
    diff --git a/dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.utils.html b/dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.utils.html index 317e4595e..eea473fbe 100644 --- a/dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.utils.html +++ b/dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.utils.html @@ -30,6 +30,9 @@ org.owasp.dependencycheck.utils ExtractionUtil (34%) +FileFilterBuilder (96%) + + Filter (92%) diff --git a/dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.xml.pom.html b/dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.xml.pom.html index 18483a46a..328b5c110 100644 --- a/dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.xml.pom.html +++ b/dependency-check-core/cobertura/frame-sourcefiles-org.owasp.dependencycheck.xml.pom.html @@ -30,7 +30,7 @@ org.owasp.dependencycheck.xml.pom PomParser (50%) -PomUtils (28%) +PomUtils (32%) diff --git a/dependency-check-core/cobertura/frame-sourcefiles.html b/dependency-check-core/cobertura/frame-sourcefiles.html index 15465d891..90db9b0d0 100644 --- a/dependency-check-core/cobertura/frame-sourcefiles.html +++ b/dependency-check-core/cobertura/frame-sourcefiles.html @@ -18,7 +18,7 @@ All Packages AbstractAnalyzer (100%) -AbstractFileTypeAnalyzer (74%) +AbstractFileTypeAnalyzer (82%) AbstractSuppressionAnalyzer (80%) @@ -51,34 +51,52 @@ All Packages AssemblyAnalyzer (67%) -CPEAnalyzer (72%) +AutoconfAnalyzer (92%) + + +BaseUpdater (70%) + + +CMakeAnalyzer (93%) + + +CPEAnalyzer (74%) + + +CPEHandler (0%) CachedWebDataSource (N/A) -CentralAnalyzer (25%) +CentralAnalyzer (27%) -CentralSearch (83%) +CentralSearch (85%) Confidence (100%) -ConnectionFactory (42%) +ConnectionFactory (33%) CorruptDatabaseException (0%) +Cpe (0%) + + CpeMemoryIndex (72%) CpeSuppressionAnalyzer (90%) -CveDB (45%) +CpeUpdater (0%) + + +CveDB (44%) CweDB (52%) @@ -93,16 +111,16 @@ All Packages DatabaseException (0%) -DatabaseProperties (20%) +DatabaseProperties (22%) DateUtil (50%) -Dependency (60%) +Dependency (66%) -DependencyBundlingAnalyzer (41%) +DependencyBundlingAnalyzer (42%) DependencyCheckScanAgent (0%) @@ -117,28 +135,28 @@ All Packages DependencyVersionUtil (89%) -DownloadTask (52%) +DownloadTask (59%) DriverLoadException (33%) -DriverLoader (56%) +DriverLoader (59%) DriverShim (17%) -Engine (53%) +Engine (52%) -EngineVersionCheck (47%) +EngineVersionCheck (51%) EscapeTool (0%) -Evidence (65%) +Evidence (67%) EvidenceCollection (73%) @@ -156,6 +174,9 @@ All Packages Fields (0%) +FileFilterBuilder (96%) + + FileNameAnalyzer (85%) @@ -165,13 +186,13 @@ All Packages Filter (92%) -HintAnalyzer (78%) +HintAnalyzer (75%) Identifier (36%) -IndexEntry (66%) +IndexEntry (63%) IndexException (0%) @@ -180,10 +201,7 @@ All Packages InvalidDataException (0%) -JarAnalyzer (62%) - - -JavaScriptAnalyzer (29%) +JarAnalyzer (63%) License (37%) @@ -198,7 +216,7 @@ All Packages Model (92%) -NexusAnalyzer (18%) +NexusAnalyzer (20%) NexusSearch (0%) @@ -222,21 +240,24 @@ All Packages NuspecParser (N/A) -NvdCve12Handler (93%) +NvdCve12Handler (93%) -NvdCve20Handler (81%) +NvdCve20Handler (81%) NvdCveAnalyzer (68%) -NvdCveInfo (100%) +NvdCveInfo (100%) NvdCveUpdater (0%) +OpenSSLAnalyzer (91%) + + Pair (42%) @@ -249,10 +270,10 @@ All Packages PomParser (50%) -PomUtils (28%) +PomUtils (32%) -ProcessTask (0%) +ProcessTask (0%) PropertyType (70%) @@ -276,9 +297,6 @@ All Packages SearchFieldAnalyzer (100%) -StandardUpdate (0%) - - SuppressionErrorHandler (11%) @@ -303,7 +321,7 @@ All Packages UpdateService (0%) -UpdateableNvdCve (93%) +UpdateableNvdCve (93%) UrlStringUtils (86%) diff --git a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.agent.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.agent.html index e78a8d4bf..81e6d2460 100644 --- a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.agent.html +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.agent.html @@ -16,7 +16,7 @@ - +
    Package # Classes Line Coverage Branch Coverage Complexity
    org.owasp.dependencycheck.agent1
    0%
    0/245
    0%
    0/112
    1.847
    org.owasp.dependencycheck.agent1
    0%
    0/244
    0%
    0/112
    1.847
    - + 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 c044a3c90..4db04b09d 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 ecb6befff..16f8fa09d 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.analyzer27
    58%
    1180/2024
    43%
    521/1210
    4.692
    org.owasp.dependencycheck.analyzer29
    62%
    1343/2157
    44%
    571/1292
    4.58
    org.owasp.dependencycheck.analyzer.exception2
    12%
    2/16
    N/A
    1
    @@ -31,9 +31,9 @@ packageTable.sort(0); AbstractAnalyzer
    100%
    3/3
    N/A
    1 - AbstractFileTypeAnalyzer
    74%
    32/43
    80%
    8/10
    1.571 + AbstractFileTypeAnalyzer
    82%
    32/39
    80%
    8/10
    1.429 - AbstractSuppressionAnalyzer
    80%
    49/61
    71%
    10/14
    3.833 + AbstractSuppressionAnalyzer
    80%
    48/60
    71%
    10/14
    3.833 AnalysisPhase
    100%
    10/10
    N/A
    0 @@ -41,42 +41,46 @@ packageTable.sort(0); AnalyzerService
    100%
    4/4
    N/A
    1 - ArchiveAnalyzer
    31%
    67/216
    22%
    20/90
    7.25 + ArchiveAnalyzer
    31%
    67/211
    22%
    20/90
    7.25 - AssemblyAnalyzer
    67%
    84/125
    50%
    25/50
    6.875 + AssemblyAnalyzer
    67%
    86/127
    50%
    25/50
    6.875 - CPEAnalyzer
    77%
    172/221
    69%
    92/132
    4.571 + AutoconfAnalyzer
    92%
    62/67
    76%
    26/34
    3.111 + + CMakeAnalyzer
    93%
    59/63
    80%
    8/10
    2 + + CPEAnalyzer
    80%
    178/221
    73%
    97/132
    4.571 CPEAnalyzer$IdentifierConfidence
    100%
    4/4
    N/A
    4.571 CPEAnalyzer$IdentifierMatch
    38%
    15/39
    16%
    4/24
    4.571 - CentralAnalyzer
    25%
    17/68
    13%
    4/30
    3.625 + CentralAnalyzer
    27%
    18/66
    13%
    4/30
    3.625 CpeSuppressionAnalyzer
    90%
    9/10
    66%
    4/6
    2.333 - DependencyBundlingAnalyzer
    41%
    63/151
    33%
    53/158
    7.923 + DependencyBundlingAnalyzer
    42%
    63/148
    31%
    51/160
    7.5 - FalsePositiveAnalyzer
    49%
    87/176
    27%
    58/212
    9.692 + FalsePositiveAnalyzer
    49%
    88/177
    25%
    58/230
    10.385 FileNameAnalyzer
    85%
    18/21
    50%
    5/10
    2.667 FileTypeAnalyzer
    N/A
    N/A
    1 - HintAnalyzer
    78%
    26/33
    54%
    12/22
    4.667 + HintAnalyzer
    75%
    30/40
    58%
    14/24
    5 - JarAnalyzer
    62%
    299/481
    50%
    163/326
    7.032 - JarAnalyzer$ClassNameInformation
    80%
    17/21
    80%
    8/10
    7.032 + JarAnalyzer
    62%
    301/481
    49%
    164/332
    7.129 + JarAnalyzer$ClassNameInformation
    80%
    17/21
    80%
    8/10
    7.129 - JavaScriptAnalyzer
    29%
    8/27
    0%
    0/4
    2 - - NexusAnalyzer
    18%
    13/69
    4%
    1/24
    3.375 + NexusAnalyzer
    20%
    14/67
    4%
    1/24
    3.375 NuspecAnalyzer
    22%
    8/35
    0%
    0/6
    2.667 NvdCveAnalyzer
    68%
    24/35
    50%
    6/12
    2.125 - PythonDistributionAnalyzer
    86%
    78/90
    65%
    30/46
    3.308 + OpenSSLAnalyzer
    91%
    33/36
    71%
    10/14
    2.125 - PythonPackageAnalyzer
    90%
    64/71
    77%
    14/18
    2.091 + PythonDistributionAnalyzer
    86%
    80/92
    65%
    30/46
    3.308 + + PythonPackageAnalyzer
    90%
    63/70
    77%
    14/18
    2.091 VulnerabilitySuppressionAnalyzer
    90%
    9/10
    66%
    4/6
    2.333 @@ -87,6 +91,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 8f29e5bdb..728bbbc1f 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 @@ -16,7 +16,7 @@ - +
    Package # Classes Line Coverage Branch Coverage Complexity
    org.owasp.dependencycheck.data.central1
    83%
    51/61
    83%
    20/24
    10
    org.owasp.dependencycheck.data.central1
    85%
    51/60
    83%
    20/24
    10
    - + 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 1cf272983..39cf8b007 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 @@ -16,7 +16,7 @@ - +
    Package # Classes Line Coverage Branch Coverage Complexity
    org.owasp.dependencycheck.data.cpe4
    65%
    95/144
    37%
    21/56
    2.452
    org.owasp.dependencycheck.data.cpe4
    65%
    94/144
    37%
    21/56
    2.452
    - + 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 12a00ae65..0084c08b1 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 1c4c8aab0..0f449e04b 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 116ba5065..8171a42dd 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 @@ -16,7 +16,7 @@ - +
    Package # Classes Line Coverage Branch Coverage Complexity
    org.owasp.dependencycheck.data.nexus2
    22%
    22/100
    10%
    3/30
    2.444
    org.owasp.dependencycheck.data.nexus2
    22%
    22/98
    10%
    3/30
    2.444
    - + 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 d936f2c55..5b2b829e5 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 3d02893d1..813d9d869 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%
    296/700
    45%
    89/196
    3.951
    org.owasp.dependencycheck.data.nvdcve9
    40%
    297/738
    45%
    91/200
    3.969
    - + 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 new file mode 100644 index 000000000..387220680 --- /dev/null +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.update.cpe.html @@ -0,0 +1,45 @@ + + + + +Coverage Report + + + + + + + +
    Coverage Report - org.owasp.dependencycheck.data.update.cpe
    +
     
    + + + + + +
    Package # Classes Line Coverage Branch Coverage Complexity
    org.owasp.dependencycheck.data.update.cpe3
    0%
    0/66
    0%
    0/18
    1.5
    + +
     
    + + + + + + + + + +
    Classes in this Package Line Coverage Branch Coverage Complexity
    CPEHandler
    0%
    0/31
    0%
    0/16
    1.611
    CPEHandler$Element
    0%
    0/17
    N/A
    1.611
    Cpe
    0%
    0/18
    0%
    0/2
    1.25
    + + + + 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 1ac1e6415..167f092f3 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 b0c9ca199..ab372796c 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 @@ -16,10 +16,10 @@ - + + - - +
    Package # Classes Line Coverage Branch Coverage Complexity
    org.owasp.dependencycheck.data.update7
    28%
    82/285
    20%
    17/84
    2.925
    org.owasp.dependencycheck.data.update6
    18%
    57/313
    15%
    16/106
    5.435
    org.owasp.dependencycheck.data.update.cpe3
    0%
    0/66
    0%
    0/18
    1.5
    org.owasp.dependencycheck.data.update.exception2
    0%
    0/12
    N/A
    1
    org.owasp.dependencycheck.data.update.task2
    34%
    51/150
    22%
    10/44
    3.556
    org.owasp.dependencycheck.data.update.xml4
    85%
    172/202
    88%
    101/114
    2.914
    org.owasp.dependencycheck.data.update.nvd8
    69%
    272/393
    71%
    116/162
    2.547
    - + 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 new file mode 100644 index 000000000..fe812e49a --- /dev/null +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.data.update.nvd.html @@ -0,0 +1,54 @@ + + + + +Coverage Report + + + + + + + +
    Coverage Report - org.owasp.dependencycheck.data.update.nvd
    +
     
    + + + + + +
    Package # Classes Line Coverage Branch Coverage Complexity
    org.owasp.dependencycheck.data.update.nvd8
    69%
    272/393
    71%
    116/162
    2.547
    + +
     
    + + + + + + + + + + + + + + + + + + +
    Classes in this Package Line Coverage Branch Coverage Complexity
    DownloadTask
    59%
    55/93
    25%
    11/44
    3.583
    NvdCve12Handler
    95%
    47/49
    86%
    26/30
    2.6
    NvdCve12Handler$Element
    77%
    7/9
    N/A
    2.6
    NvdCve20Handler
    80%
    100/125
    89%
    75/84
    3.04
    NvdCve20Handler$Element
    94%
    18/19
    N/A
    3.04
    NvdCveInfo
    100%
    17/17
    N/A
    1
    ProcessTask
    0%
    0/51
    N/A
    3.5
    UpdateableNvdCve
    93%
    28/30
    100%
    4/4
    1.25
    + + + + 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 e7acf9a9b..5f218756d 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
    62%
    411/655
    39%
    180/454
    2.489
    org.owasp.dependencycheck.dependency14
    64%
    379/585
    46%
    149/318
    2.072
    - + 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 47d896214..f42c9768b 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 4260ffe70..d4d12835b 100644 --- a/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.html +++ b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.html @@ -16,27 +16,27 @@ - - - + + + - - + + - + - - + + + - - - + + - + - - + +
    Package # Classes Line Coverage Branch Coverage Complexity
    org.owasp.dependencycheck1
    53%
    113/213
    53%
    41/76
    3.333
    org.owasp.dependencycheck.agent1
    0%
    0/245
    0%
    0/112
    1.847
    org.owasp.dependencycheck.analyzer27
    58%
    1180/2024
    43%
    521/1210
    4.692
    org.owasp.dependencycheck1
    52%
    102/194
    54%
    37/68
    3.167
    org.owasp.dependencycheck.agent1
    0%
    0/244
    0%
    0/112
    1.847
    org.owasp.dependencycheck.analyzer29
    62%
    1343/2157
    44%
    571/1292
    4.58
    org.owasp.dependencycheck.analyzer.exception2
    12%
    2/16
    N/A
    1
    org.owasp.dependencycheck.data.central1
    83%
    51/61
    83%
    20/24
    10
    org.owasp.dependencycheck.data.cpe4
    65%
    95/144
    37%
    21/56
    2.452
    org.owasp.dependencycheck.data.central1
    85%
    51/60
    83%
    20/24
    10
    org.owasp.dependencycheck.data.cpe4
    65%
    94/144
    37%
    21/56
    2.452
    org.owasp.dependencycheck.data.cwe2
    39%
    13/33
    25%
    2/8
    2.8
    org.owasp.dependencycheck.data.lucene8
    90%
    98/108
    92%
    35/38
    2.696
    org.owasp.dependencycheck.data.nexus2
    22%
    22/100
    10%
    3/30
    2.444
    org.owasp.dependencycheck.data.nexus2
    22%
    22/98
    10%
    3/30
    2.444
    org.owasp.dependencycheck.data.nuget4
    70%
    41/58
    15%
    6/40
    2.238
    org.owasp.dependencycheck.data.nvdcve9
    42%
    296/700
    45%
    89/196
    3.951
    org.owasp.dependencycheck.data.update7
    28%
    82/285
    20%
    17/84
    2.925
    org.owasp.dependencycheck.data.nvdcve9
    40%
    297/738
    45%
    91/200
    3.969
    org.owasp.dependencycheck.data.update6
    18%
    57/313
    15%
    16/106
    5.435
    org.owasp.dependencycheck.data.update.cpe3
    0%
    0/66
    0%
    0/18
    1.5
    org.owasp.dependencycheck.data.update.exception2
    0%
    0/12
    N/A
    1
    org.owasp.dependencycheck.data.update.task2
    34%
    51/150
    22%
    10/44
    3.556
    org.owasp.dependencycheck.data.update.xml4
    85%
    172/202
    88%
    101/114
    2.914
    org.owasp.dependencycheck.dependency14
    62%
    411/655
    39%
    180/454
    2.489
    org.owasp.dependencycheck.data.update.nvd8
    69%
    272/393
    71%
    116/162
    2.547
    org.owasp.dependencycheck.dependency14
    64%
    379/585
    46%
    149/318
    2.072
    org.owasp.dependencycheck.exception2
    0%
    0/16
    N/A
    1
    org.owasp.dependencycheck.reporting4
    0%
    0/138
    0%
    0/70
    4.25
    org.owasp.dependencycheck.reporting4
    0%
    0/152
    0%
    0/76
    4.467
    org.owasp.dependencycheck.suppression6
    72%
    222/307
    62%
    112/178
    3.073
    org.owasp.dependencycheck.utils11
    61%
    214/348
    59%
    102/172
    3.765
    org.owasp.dependencycheck.xml.pom6
    59%
    137/229
    54%
    40/74
    2.511
    org.owasp.dependencycheck.utils12
    64%
    237/370
    61%
    116/188
    3.632
    org.owasp.dependencycheck.xml.pom6
    61%
    137/223
    54%
    40/74
    2.511
    - + 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 ff02bb1ad..eadc89077 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 @@ -16,7 +16,7 @@ - +
    Package # Classes Line Coverage Branch Coverage Complexity
    org.owasp.dependencycheck.reporting4
    0%
    0/138
    0%
    0/70
    4.25
    org.owasp.dependencycheck.reporting4
    0%
    0/152
    0%
    0/76
    4.467
    - + 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 a1a412240..f41566eab 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 @@ -47,6 +47,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.utils.html b/dependency-check-core/cobertura/frame-summary-org.owasp.dependencycheck.utils.html index fe649ea81..161404dd1 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
    61%
    214/348
    59%
    102/172
    3.765
    org.owasp.dependencycheck.utils12
    64%
    237/370
    61%
    116/188
    3.632
    - + 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 cd1d8c5c1..0b1f782e4 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.pom6
    59%
    137/229
    54%
    40/74
    2.511
    org.owasp.dependencycheck.xml.pom6
    61%
    137/223
    54%
    40/74
    2.511
    - + diff --git a/dependency-check-core/cobertura/frame-summary.html b/dependency-check-core/cobertura/frame-summary.html index d2a6e8487..3c0cf48c5 100644 --- a/dependency-check-core/cobertura/frame-summary.html +++ b/dependency-check-core/cobertura/frame-summary.html @@ -16,28 +16,28 @@ - - - - + + + + - - + + - + - - + + + - - - + + - + - - + +
    Package # Classes Line Coverage Branch Coverage Complexity
    All Packages119
    52%
    3200/6044
    43%
    1300/2980
    3.219
    org.owasp.dependencycheck1
    53%
    113/213
    53%
    41/76
    3.333
    org.owasp.dependencycheck.agent1
    0%
    0/245
    0%
    0/112
    1.847
    org.owasp.dependencycheck.analyzer27
    58%
    1180/2024
    43%
    521/1210
    4.692
    All Packages126
    53%
    3367/6287
    44%
    1335/2988
    3.116
    org.owasp.dependencycheck1
    52%
    102/194
    54%
    37/68
    3.167
    org.owasp.dependencycheck.agent1
    0%
    0/244
    0%
    0/112
    1.847
    org.owasp.dependencycheck.analyzer29
    62%
    1343/2157
    44%
    571/1292
    4.58
    org.owasp.dependencycheck.analyzer.exception2
    12%
    2/16
    N/A
    1
    org.owasp.dependencycheck.data.central1
    83%
    51/61
    83%
    20/24
    10
    org.owasp.dependencycheck.data.cpe4
    65%
    95/144
    37%
    21/56
    2.452
    org.owasp.dependencycheck.data.central1
    85%
    51/60
    83%
    20/24
    10
    org.owasp.dependencycheck.data.cpe4
    65%
    94/144
    37%
    21/56
    2.452
    org.owasp.dependencycheck.data.cwe2
    39%
    13/33
    25%
    2/8
    2.8
    org.owasp.dependencycheck.data.lucene8
    90%
    98/108
    92%
    35/38
    2.696
    org.owasp.dependencycheck.data.nexus2
    22%
    22/100
    10%
    3/30
    2.444
    org.owasp.dependencycheck.data.nexus2
    22%
    22/98
    10%
    3/30
    2.444
    org.owasp.dependencycheck.data.nuget4
    70%
    41/58
    15%
    6/40
    2.238
    org.owasp.dependencycheck.data.nvdcve9
    42%
    296/700
    45%
    89/196
    3.951
    org.owasp.dependencycheck.data.update7
    28%
    82/285
    20%
    17/84
    2.925
    org.owasp.dependencycheck.data.nvdcve9
    40%
    297/738
    45%
    91/200
    3.969
    org.owasp.dependencycheck.data.update6
    18%
    57/313
    15%
    16/106
    5.435
    org.owasp.dependencycheck.data.update.cpe3
    0%
    0/66
    0%
    0/18
    1.5
    org.owasp.dependencycheck.data.update.exception2
    0%
    0/12
    N/A
    1
    org.owasp.dependencycheck.data.update.task2
    34%
    51/150
    22%
    10/44
    3.556
    org.owasp.dependencycheck.data.update.xml4
    85%
    172/202
    88%
    101/114
    2.914
    org.owasp.dependencycheck.dependency14
    62%
    411/655
    39%
    180/454
    2.489
    org.owasp.dependencycheck.data.update.nvd8
    69%
    272/393
    71%
    116/162
    2.547
    org.owasp.dependencycheck.dependency14
    64%
    379/585
    46%
    149/318
    2.072
    org.owasp.dependencycheck.exception2
    0%
    0/16
    N/A
    1
    org.owasp.dependencycheck.reporting4
    0%
    0/138
    0%
    0/70
    4.25
    org.owasp.dependencycheck.reporting4
    0%
    0/152
    0%
    0/76
    4.467
    org.owasp.dependencycheck.suppression6
    72%
    222/307
    62%
    112/178
    3.073
    org.owasp.dependencycheck.utils11
    61%
    214/348
    59%
    102/172
    3.765
    org.owasp.dependencycheck.xml.pom6
    59%
    137/229
    54%
    40/74
    2.511
    org.owasp.dependencycheck.utils12
    64%
    237/370
    61%
    116/188
    3.632
    org.owasp.dependencycheck.xml.pom6
    61%
    137/223
    54%
    40/74
    2.511
    - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.Engine.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.Engine.html index 977881f75..561bf9353 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
    53%
    113/213
    53%
    41/76
    3.333
    Engine
    52%
    102/194
    54%
    37/68
    3.167
     
    @@ -56,273 +56,273 @@  19  
     
     20   -
     import java.io.File;
    -  21   -
     import java.util.ArrayList;
    -  22   -
     import java.util.EnumMap;
    -  23   -
     import java.util.HashSet;
    -  24   -
     import java.util.Iterator;
    -  25   -
     import java.util.List;
    -  26   -
     import java.util.Set;
    -  27   -
     import java.util.logging.Level;
    -  28   -
     import java.util.logging.Logger;
    -  29  
     import org.owasp.dependencycheck.analyzer.AnalysisPhase;
    -  30   +  21  
     import org.owasp.dependencycheck.analyzer.Analyzer;
    -  31   +  22  
     import org.owasp.dependencycheck.analyzer.AnalyzerService;
    -  32   +  23  
     import org.owasp.dependencycheck.analyzer.FileTypeAnalyzer;
    -  33   +  24  
     import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
    -  34   +  25  
     import org.owasp.dependencycheck.data.nvdcve.ConnectionFactory;
    -  35   +  26  
     import org.owasp.dependencycheck.data.nvdcve.CveDB;
    -  36   +  27  
     import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
    -  37   +  28  
     import org.owasp.dependencycheck.data.update.CachedWebDataSource;
    -  38   +  29  
     import org.owasp.dependencycheck.data.update.UpdateService;
    -  39   +  30  
     import org.owasp.dependencycheck.data.update.exception.UpdateException;
    -  40   +  31  
     import org.owasp.dependencycheck.dependency.Dependency;
    -  41   +  32  
     import org.owasp.dependencycheck.exception.NoDataException;
    -  42   -
     import org.owasp.dependencycheck.utils.FileUtils;
    -  43   +  33  
     import org.owasp.dependencycheck.utils.InvalidSettingException;
    -  44   +  34  
     import org.owasp.dependencycheck.utils.Settings;
    +  35   +
     import org.slf4j.Logger;
    +  36   +
     import org.slf4j.LoggerFactory;
    +  37   +
     
    +  38   +
     import java.io.File;
    +  39   +
     import java.io.FileFilter;
    +  40   +
     import java.util.ArrayList;
    +  41   +
     import java.util.EnumMap;
    +  42   +
     import java.util.HashSet;
    +  43   +
     import java.util.Iterator;
    +  44   +
     import java.util.List;
     45   -
     
    +
     import java.util.Set;
     46   -
     /**
    +
     
     47   -
      * Scans files, directories, etc. for Dependencies. Analyzers are loaded and used to process the files found by the scan, if a
    +
     /**
     48   -
      * file is encountered and an Analyzer is associated with the file type then the file is turned into a dependency.
    +
      * Scans files, directories, etc. for Dependencies. Analyzers are loaded and used to process the files found by the scan, if a
     49   -
      *
    +
      * file is encountered and an Analyzer is associated with the file type then the file is turned into a dependency.
     50   -
      * @author Jeremy Long
    +
      *
     51   -
      */
    +
      * @author Jeremy Long
     52   -
     public class Engine {
    +
      */
     53   -
     
    +
     public class Engine implements FileFilter {
     54   -
         /**
    +
     
     55   -
          * The list of dependencies.
    +
         /**
     56   +
          * The list of dependencies.
    +  57  
          */
    -  57  1
         private List<Dependency> dependencies = new ArrayList<Dependency>();
    -  58   -
         /**
    +  58  16
         private List<Dependency> dependencies = new ArrayList<Dependency>();
     59   -
          * A Map of analyzers grouped by Analysis phase.
    +
         /**
     60   -
          */
    -  61  1
         private EnumMap<AnalysisPhase, List<Analyzer>> analyzers = new EnumMap<AnalysisPhase, List<Analyzer>>(AnalysisPhase.class);
    -  62   -
     
    -  63   -
         /**
    -  64  
          * A Map of analyzers grouped by Analysis phase.
    +  61   +
          */
    +  62  16
         private EnumMap<AnalysisPhase, List<Analyzer>> analyzers = new EnumMap<AnalysisPhase, List<Analyzer>>(AnalysisPhase.class);
    +  63   +
     
    +  64   +
         /**
     65   +
          * A Map of analyzers grouped by Analysis phase.
    +  66  
          */
    -  66  1
         private Set<FileTypeAnalyzer> fileTypeAnalyzers = new HashSet<FileTypeAnalyzer>();
    -  67   -
     
    +  67  16
         private Set<FileTypeAnalyzer> fileTypeAnalyzers = new HashSet<FileTypeAnalyzer>();
     68   -
         /**
    +
     
     69   -
          * The ClassLoader to use when dynamically loading Analyzer and Update services.
    +
         /**
     70   +
          * The ClassLoader to use when dynamically loading Analyzer and Update services.
    +  71  
          */
    -  71  1
         private ClassLoader serviceClassLoader = Thread.currentThread().getContextClassLoader();
    -  72   -
         /**
    +  72  16
         private ClassLoader serviceClassLoader = Thread.currentThread().getContextClassLoader();
     73   -
          * The Logger for use throughout the class.
    +
         /**
     74   +
          * The Logger for use throughout the class.
    +  75  
          */
    -  75  1
         private static final Logger LOGGER = Logger.getLogger(Engine.class.getName());
    -  76   -
     
    +  76  8
         private static final Logger LOGGER = LoggerFactory.getLogger(Engine.class);
     77   -
         /**
    +
     
     78   -
          * Creates a new Engine.
    +
         /**
     79   -
          *
    -  80   -
          * @throws DatabaseException thrown if there is an error connecting to the database
    -  81   -
          */
    -  82  1
         public Engine() throws DatabaseException {
    -  83  1
             initializeEngine();
    -  84  1
         }
    -  85   -
     
    -  86   -
         /**
    -  87  
          * Creates a new Engine.
    +  80   +
          *
    +  81   +
          * @throws DatabaseException thrown if there is an error connecting to the database
    +  82   +
          */
    +  83  16
         public Engine() throws DatabaseException {
    +  84  16
             initializeEngine();
    +  85  16
         }
    +  86   +
     
    +  87   +
         /**
     88   -
          *
    +
          * Creates a new Engine.
     89   -
          * @param serviceClassLoader a reference the class loader being used
    +
          *
     90   -
          * @throws DatabaseException thrown if there is an error connecting to the database
    +
          * @param serviceClassLoader a reference the class loader being used
     91   -
          */
    -  92  0
         public Engine(ClassLoader serviceClassLoader) throws DatabaseException {
    -  93  0
             this.serviceClassLoader = serviceClassLoader;
    -  94  0
             initializeEngine();
    -  95  0
         }
    -  96   -
     
    -  97   -
         /**
    -  98   -
          * Creates a new Engine using the specified classloader to dynamically load Analyzer and Update services.
    -  99   -
          *
    -  100  
          * @throws DatabaseException thrown if there is an error connecting to the database
    +  92   +
          */
    +  93  0
         public Engine(ClassLoader serviceClassLoader) throws DatabaseException {
    +  94  0
             this.serviceClassLoader = serviceClassLoader;
    +  95  0
             initializeEngine();
    +  96  0
         }
    +  97   +
     
    +  98   +
         /**
    +  99   +
          * Creates a new Engine using the specified classloader to dynamically load Analyzer and Update services.
    +  100   +
          *
     101   -
          */
    +
          * @throws DatabaseException thrown if there is an error connecting to the database
     102   +
          */
    +  103  
         protected final void initializeEngine() throws DatabaseException {
    -  103  1
             ConnectionFactory.initialize();
    -  104  1
             loadAnalyzers();
    -  105  1
         }
    -  106   -
     
    +  104  16
             ConnectionFactory.initialize();
    +  105  16
             loadAnalyzers();
    +  106  16
         }
     107   -
         /**
    +
     
     108   -
          * Properly cleans up resources allocated during analysis.
    +
         /**
     109   -
          */
    +
          * Properly cleans up resources allocated during analysis.
     110   +
          */
    +  111  
         public void cleanup() {
    -  111  0
             ConnectionFactory.cleanup();
    -  112  0
         }
    -  113   -
     
    +  112  0
             ConnectionFactory.cleanup();
    +  113  0
         }
     114   -
         /**
    +
     
     115   -
          * Loads the analyzers specified in the configuration file (or system properties).
    +
         /**
     116   -
          */
    +
          * Loads the analyzers specified in the configuration file (or system properties).
     117   +
          */
    +  118  
         private void loadAnalyzers() {
    -  118  1
             if (!analyzers.isEmpty()) {
    -  119  0
                 return;
    -  120   -
             }
    -  121  10
             for (AnalysisPhase phase : AnalysisPhase.values()) {
    -  122  9
                 analyzers.put(phase, new ArrayList<Analyzer>());
    -  123   +  119  16
             if (!analyzers.isEmpty()) {
    +  120  0
                 return;
    +  121  
             }
    +  122  160
             for (AnalysisPhase phase : AnalysisPhase.values()) {
    +  123  144
                 analyzers.put(phase, new ArrayList<Analyzer>());
     124   +
             }
    +  125  
     
    -  125  1
             final AnalyzerService service = new AnalyzerService(serviceClassLoader);
    -  126  1
             final Iterator<Analyzer> iterator = service.getAnalyzers();
    -  127  17
             while (iterator.hasNext()) {
    -  128  16
                 final Analyzer a = iterator.next();
    -  129  16
                 analyzers.get(a.getAnalysisPhase()).add(a);
    -  130  16
                 if (a instanceof FileTypeAnalyzer) {
    -  131  8
                     this.fileTypeAnalyzers.add((FileTypeAnalyzer) a);
    -  132   +  126  16
             final AnalyzerService service = new AnalyzerService(serviceClassLoader);
    +  127  16
             final Iterator<Analyzer> iterator = service.getAnalyzers();
    +  128  320
             while (iterator.hasNext()) {
    +  129  304
                 final Analyzer a = iterator.next();
    +  130  304
                 analyzers.get(a.getAnalysisPhase()).add(a);
    +  131  304
                 if (a instanceof FileTypeAnalyzer) {
    +  132  176
                     this.fileTypeAnalyzers.add((FileTypeAnalyzer) a);
    +  133  
                 }
    -  133  16
             }
    -  134  1
         }
    -  135   -
     
    +  134  304
             }
    +  135  16
         }
     136   -
         /**
    +
     
     137   -
          * Get the List of the analyzers for a specific phase of analysis.
    +
         /**
     138   -
          *
    +
          * Get the List of the analyzers for a specific phase of analysis.
     139   -
          * @param phase the phase to get the configured analyzers.
    +
          *
     140   -
          * @return the analyzers loaded
    +
          * @param phase the phase to get the configured analyzers.
     141   -
          */
    +
          * @return the analyzers loaded
     142   +
          */
    +  143  
         public List<Analyzer> getAnalyzers(AnalysisPhase phase) {
    -  143  0
             return analyzers.get(phase);
    -  144   -
         }
    +  144  0
             return analyzers.get(phase);
     145   -
     
    -  146   -
         /**
    -  147   -
          * Get the dependencies identified.
    -  148   -
          *
    -  149   -
          * @return the dependencies identified
    -  150   -
          */
    -  151   -
         public List<Dependency> getDependencies() {
    -  152  10
             return dependencies;
    -  153  
         }
    -  154   +  146  
     
    -  155   +  147  
         /**
    -  156   -
          * Sets the dependencies.
    -  157   +  148   +
          * Get the dependencies identified.
    +  149  
          *
    -  158   -
          * @param dependencies the dependencies
    -  159   +  150   +
          * @return the dependencies identified
    +  151  
          */
    -  160   -
         public void setDependencies(List<Dependency> dependencies) {
    -  161  0
             this.dependencies = dependencies;
    -  162  0
         }
    -  163   +  152   +
         public List<Dependency> getDependencies() {
    +  153  120
             return dependencies;
    +  154   +
         }
    +  155  
     
    -  164   +  156  
         /**
    +  157   +
          * Sets the dependencies.
    +  158   +
          *
    +  159   +
          * @param dependencies the dependencies
    +  160   +
          */
    +  161   +
         public void setDependencies(List<Dependency> dependencies) {
    +  162  0
             this.dependencies = dependencies;
    +  163  0
         }
    +  164   +
     
     165   -
          * Scans an array of files or directories. If a directory is specified, it will be scanned recursively. Any dependencies
    +
         /**
     166   -
          * identified are added to the dependency collection.
    +
          * Scans an array of files or directories. If a directory is specified, it will be scanned recursively. Any dependencies
     167   -
          *
    +
          * identified are added to the dependency collection.
     168   -
          * @param paths an array of paths to files or directories to be analyzed
    -  169   -
          * @return the list of dependencies scanned
    -  170  
          *
    +  169   +
          * @param paths an array of paths to files or directories to be analyzed
    +  170   +
          * @return the list of dependencies scanned
     171  
          * @since v0.3.2.5
     172   @@ -379,446 +379,457 @@  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   -
         /**
    +
          * Scans a list of files or directories. If a directory is specified, it will be scanned recursively. Any dependencies
     218   -
          * Scans a list of files or directories. If a directory is specified, it will be scanned recursively. Any dependencies
    +
          * identified are added to the dependency collection.
     219   -
          * identified are added to the dependency collection.
    +
          *
     220   -
          *
    +
          * @param files a set of paths to files or directories to be analyzed
     221   -
          * @param files a set of paths to files or directories to be analyzed
    +
          * @return the list of dependencies scanned
     222   -
          * @return the list of dependencies scanned
    +
          * @since v0.3.2.5
     223   -
          *
    +
          */
     224   -
          * @since v0.3.2.5
    -  225   -
          */
    -  226  
         public List<Dependency> scan(Set<File> files) {
    -  227  0
             final List<Dependency> deps = new ArrayList<Dependency>();
    -  228  0
             for (File file : files) {
    -  229  0
                 final List<Dependency> d = scan(file);
    -  230  0
                 if (d != null) {
    -  231  0
                     deps.addAll(d);
    -  232   +  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  
                 }
    -  233  0
             }
    -  234  0
             return deps;
    +  231  0
             }
    +  232  0
             return deps;
    +  233   +
         }
    +  234   +
     
     235   -
         }
    +
         /**
     236   -
     
    -  237   -
         /**
    -  238  
          * Scans a list of files or directories. If a directory is specified, it will be scanned recursively. Any dependencies
    -  239   +  237  
          * identified are added to the dependency collection.
    -  240   +  238  
          *
    -  241   +  239  
          * @param files a set of paths to files or directories to be analyzed
    -  242   +  240  
          * @return the list of dependencies scanned
    -  243   -
          *
    -  244   +  241  
          * @since v0.3.2.5
    -  245   +  242  
          */
    -  246   +  243  
         public List<Dependency> scan(List<File> files) {
    -  247  0
             final List<Dependency> deps = new ArrayList<Dependency>();
    -  248  0
             for (File file : files) {
    -  249  0
                 final List<Dependency> d = scan(file);
    -  250  0
                 if (d != null) {
    -  251  0
                     deps.addAll(d);
    +  244  0
             final List<Dependency> deps = new ArrayList<Dependency>();
    +  245  0
             for (File file : files) {
    +  246  0
                 final List<Dependency> d = scan(file);
    +  247  0
                 if (d != null) {
    +  248  0
                     deps.addAll(d);
    +  249   +
                 }
    +  250  0
             }
    +  251  0
             return deps;
     252   -
                 }
    -  253  0
             }
    -  254  0
             return deps;
    +
         }
    +  253   +
     
    +  254   +
         /**
     255   -
         }
    -  256   -
     
    -  257   -
         /**
    -  258  
          * Scans a given file or directory. If a directory is specified, it will be scanned recursively. Any dependencies identified
    -  259   +  256  
          * are added to the dependency collection.
    -  260   +  257  
          *
    -  261   +  258  
          * @param file the path to a file or directory to be analyzed
    -  262   +  259  
          * @return the list of dependencies scanned
    -  263   -
          *
    -  264   +  260  
          * @since v0.3.2.4
    -  265   -
          *
    -  266   +  261  
          */
    -  267   +  262  
         public List<Dependency> scan(File file) {
    -  268  4
             if (file.exists()) {
    -  269  4
                 if (file.isDirectory()) {
    -  270  2
                     return scanDirectory(file);
    -  271   +  263  32
             if (file.exists()) {
    +  264  32
                 if (file.isDirectory()) {
    +  265  16
                     return scanDirectory(file);
    +  266  
                 } else {
    -  272  2
                     final Dependency d = scanFile(file);
    -  273  2
                     if (d != null) {
    -  274  2
                         final List<Dependency> deps = new ArrayList<Dependency>();
    -  275  2
                         deps.add(d);
    -  276  2
                         return deps;
    +  267  16
                     final Dependency d = scanFile(file);
    +  268  16
                     if (d != null) {
    +  269  16
                         final List<Dependency> deps = new ArrayList<Dependency>();
    +  270  16
                         deps.add(d);
    +  271  16
                         return deps;
    +  272   +
                     }
    +  273   +
                 }
    +  274   +
             }
    +  275  0
             return null;
    +  276   +
         }
     277   -
                     }
    +
     
     278   -
                 }
    +
         /**
     279   -
             }
    -  280  0
             return null;
    -  281   -
         }
    -  282   -
     
    -  283   -
         /**
    -  284  
          * Recursively scans files and directories. Any dependencies identified are added to the dependency collection.
    -  285   +  280  
          *
    -  286   +  281  
          * @param dir the directory to scan
    -  287   +  282  
          * @return the list of Dependency objects scanned
    -  288   +  283  
          */
    -  289   +  284  
         protected List<Dependency> scanDirectory(File dir) {
    -  290  38
             final File[] files = dir.listFiles();
    -  291  38
             final List<Dependency> deps = new ArrayList<Dependency>();
    -  292  38
             if (files != null) {
    -  293  74
                 for (File f : files) {
    -  294  36
                     if (f.isDirectory()) {
    -  295  36
                         final List<Dependency> d = scanDirectory(f);
    -  296  36
                         if (d != null) {
    -  297  36
                             deps.addAll(d);
    -  298   +  285  304
             final File[] files = dir.listFiles();
    +  286  304
             final List<Dependency> deps = new ArrayList<Dependency>();
    +  287  304
             if (files != null) {
    +  288  592
                 for (File f : files) {
    +  289  288
                     if (f.isDirectory()) {
    +  290  288
                         final List<Dependency> d = scanDirectory(f);
    +  291  288
                         if (d != null) {
    +  292  288
                             deps.addAll(d);
    +  293  
                         }
    -  299  36
                     } else {
    -  300  0
                         final Dependency d = scanFile(f);
    -  301  0
                         deps.add(d);
    -  302   +  294  288
                     } else {
    +  295  0
                         final Dependency d = scanFile(f);
    +  296  0
                         deps.add(d);
    +  297  
                     }
    +  298   +
                 }
    +  299   +
             }
    +  300  304
             return deps;
    +  301   +
         }
    +  302   +
     
     303   -
                 }
    +
         /**
     304   -
             }
    -  305  38
             return deps;
    -  306   -
         }
    -  307   -
     
    -  308   -
         /**
    -  309  
          * Scans a specified file. If a dependency is identified it is added to the dependency collection.
    -  310   +  305  
          *
    -  311   +  306  
          * @param file The file to scan
    -  312   +  307  
          * @return the scanned dependency
    -  313   +  308  
          */
    -  314   +  309  
         protected Dependency scanFile(File file) {
    -  315  2
             if (!file.isFile()) {
    -  316  0
                 final String msg = String.format("Path passed to scanFile(File) is not a file: %s. Skipping the file.", file.toString());
    -  317  0
                 LOGGER.log(Level.FINE, msg);
    -  318  0
                 return null;
    -  319   -
             }
    -  320  2
             final String fileName = file.getName();
    -  321  2
             String extension = FileUtils.getFileExtension(fileName);
    -  322  2
             if (null == extension) {
    -  323  0
                 extension = fileName;
    -  324   -
             }
    -  325  2
             Dependency dependency = null;
    -  326  2
             if (supportsExtension(extension)) {
    -  327  2
                 dependency = new Dependency(file);
    -  328  2
                 if (extension == null ? fileName == null : extension.equals(fileName)) {
    -  329  0
                     dependency.setFileExtension(extension);
    -  330   +  310  16
             Dependency dependency = null;
    +  311  16
             if (file.isFile()) {
    +  312  16
                 if (accept(file)) {
    +  313  16
                     dependency = new Dependency(file);
    +  314  16
                     dependencies.add(dependency);
    +  315  
                 }
    -  331  2
                 dependencies.add(dependency);
    -  332   +  316   +
             } else {
    +  317  0
                 LOGGER.debug("Path passed to scanFile(File) is not a file: {}. Skipping the file.", file);
    +  318  
             }
    -  333  2
             return dependency;
    -  334   +  319  16
             return dependency;
    +  320  
         }
    -  335   +  321  
     
    -  336   +  322  
         /**
    -  337   -
          * Runs the analyzers against all of the dependencies.
    -  338   +  323   +
          * Runs the analyzers against all of the dependencies. Since the mutable dependencies list is exposed via
    +  324   +
          * {@link #getDependencies()}, this method iterates over a copy of the dependencies list. Thus, the potential for
    +  325   +
          * {@link java.util.ConcurrentModificationException}s is avoided, and analyzers may safely add or remove entries from the
    +  326   +
          * dependencies list.
    +  327  
          */
    -  339   +  328  
         public void analyzeDependencies() {
    -  340  1
             boolean autoUpdate = true;
    -  341   +  329  8
             boolean autoUpdate = true;
    +  330  
             try {
    -  342  1
                 autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE);
    -  343  0
             } catch (InvalidSettingException ex) {
    -  344  0
                 LOGGER.log(Level.FINE, "Invalid setting for auto-update; using true.");
    -  345  1
             }
    -  346  1
             if (autoUpdate) {
    -  347  0
                 doUpdates();
    -  348   +  331  8
                 autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE);
    +  332  0
             } catch (InvalidSettingException ex) {
    +  333  0
                 LOGGER.debug("Invalid setting for auto-update; using true.");
    +  334  8
             }
    +  335  8
             if (autoUpdate) {
    +  336  0
                 doUpdates();
    +  337  
             }
    -  349   +  338  
     
    -  350   +  339  
             //need to ensure that data exists
    -  351   +  340  
             try {
    -  352  1
                 ensureDataExists();
    -  353  0
             } catch (NoDataException ex) {
    -  354  0
                 final String msg = String.format("%s%n%nUnable to continue dependency-check analysis.", ex.getMessage());
    -  355  0
                 LOGGER.log(Level.SEVERE, msg);
    -  356  0
                 LOGGER.log(Level.FINE, null, ex);
    -  357  0
                 return;
    -  358  0
             } catch (DatabaseException ex) {
    -  359  0
                 final String msg = String.format("%s%n%nUnable to continue dependency-check analysis.", ex.getMessage());
    -  360  0
                 LOGGER.log(Level.SEVERE, msg);
    -  361  0
                 LOGGER.log(Level.FINE, null, ex);
    -  362  0
                 return;
    -  363   +  341  8
                 ensureDataExists();
    +  342  0
             } catch (NoDataException ex) {
    +  343  0
                 LOGGER.error("{}\n\nUnable to continue dependency-check analysis.", ex.getMessage());
    +  344  0
                 LOGGER.debug("", ex);
    +  345  0
                 return;
    +  346  0
             } catch (DatabaseException ex) {
    +  347  0
                 LOGGER.error("{}\n\nUnable to continue dependency-check analysis.", ex.getMessage());
    +  348  0
                 LOGGER.debug("", ex);
    +  349  0
                 return;
    +  350  
     
    -  364  1
             }
    -  365   +  351  8
             }
    +  352  
     
    -  366  1
             final String logHeader = String.format("%n"
    -  367   -
                     + "----------------------------------------------------%n"
    -  368   -
                     + "BEGIN ANALYSIS%n"
    -  369   -
                     + "----------------------------------------------------");
    -  370  1
             LOGGER.log(Level.FINE, logHeader);
    -  371  1
             LOGGER.log(Level.INFO, "Analysis Starting");
    -  372   +  353  8
             LOGGER.debug("\n----------------------------------------------------\nBEGIN ANALYSIS\n----------------------------------------------------");
    +  354  8
             LOGGER.info("Analysis Starting");
    +  355  
     
    -  373   +  356  
             // analysis phases
    -  374  10
             for (AnalysisPhase phase : AnalysisPhase.values()) {
    -  375  9
                 final List<Analyzer> analyzerList = analyzers.get(phase);
    -  376   +  357  80
             for (AnalysisPhase phase : AnalysisPhase.values()) {
    +  358  72
                 final List<Analyzer> analyzerList = analyzers.get(phase);
    +  359  
     
    -  377  9
                 for (Analyzer a : analyzerList) {
    -  378  16
                     a = initializeAnalyzer(a);
    -  379   +  360  72
                 for (Analyzer a : analyzerList) {
    +  361  152
                     a = initializeAnalyzer(a);
    +  362  
     
    -  380   +  363  
                     /* need to create a copy of the collection because some of the
    -  381   +  364  
                      * analyzers may modify it. This prevents ConcurrentModificationExceptions.
    -  382   +  365  
                      * This is okay for adds/deletes because it happens per analyzer.
    -  383   +  366  
                      */
    -  384  16
                     final String msg = String.format("Begin Analyzer '%s'", a.getName());
    -  385  16
                     LOGGER.log(Level.FINE, msg);
    -  386  16
                     final Set<Dependency> dependencySet = new HashSet<Dependency>();
    -  387  16
                     dependencySet.addAll(dependencies);
    -  388  16
                     for (Dependency d : dependencySet) {
    -  389  32
                         boolean shouldAnalyze = true;
    -  390  32
                         if (a instanceof FileTypeAnalyzer) {
    -  391  16
                             final FileTypeAnalyzer fAnalyzer = (FileTypeAnalyzer) a;
    -  392  16
                             shouldAnalyze = fAnalyzer.supportsExtension(d.getFileExtension());
    -  393   +  367  152
                     LOGGER.debug("Begin Analyzer '{}'", a.getName());
    +  368  152
                     final Set<Dependency> dependencySet = new HashSet<Dependency>();
    +  369  152
                     dependencySet.addAll(dependencies);
    +  370  152
                     for (Dependency d : dependencySet) {
    +  371  304
                         boolean shouldAnalyze = true;
    +  372  304
                         if (a instanceof FileTypeAnalyzer) {
    +  373  176
                             final FileTypeAnalyzer fAnalyzer = (FileTypeAnalyzer) a;
    +  374  176
                             shouldAnalyze = fAnalyzer.accept(d.getActualFile());
    +  375  
                         }
    -  394  32
                         if (shouldAnalyze) {
    -  395  20
                             final String msgFile = String.format("Begin Analysis of '%s'", d.getActualFilePath());
    -  396  20
                             LOGGER.log(Level.FINE, msgFile);
    -  397   +  376  304
                         if (shouldAnalyze) {
    +  377  160
                             LOGGER.debug("Begin Analysis of '{}'", d.getActualFilePath());
    +  378  
                             try {
    -  398  20
                                 a.analyze(d, this);
    -  399  0
                             } catch (AnalysisException ex) {
    -  400  0
                                 final String exMsg = String.format("An error occurred while analyzing '%s'.", d.getActualFilePath());
    -  401  0
                                 LOGGER.log(Level.WARNING, exMsg);
    -  402  0
                                 LOGGER.log(Level.FINE, "", ex);
    -  403  0
                             } catch (Throwable ex) {
    -  404  0
                                 final String axMsg = String.format("An unexpected error occurred during analysis of '%s'", d.getActualFilePath());
    -  405   +  379  160
                                 a.analyze(d, this);
    +  380  0
                             } catch (AnalysisException ex) {
    +  381  0
                                 LOGGER.warn("An error occurred while analyzing '{}'.", d.getActualFilePath());
    +  382  0
                                 LOGGER.debug("", ex);
    +  383  0
                             } catch (Throwable ex) {
    +  384  
                                 //final AnalysisException ax = new AnalysisException(axMsg, ex);
    -  406  0
                                 LOGGER.log(Level.WARNING, axMsg);
    -  407  0
                                 LOGGER.log(Level.FINE, "", ex);
    -  408  20
                             }
    -  409   +  385  0
                                 LOGGER.warn("An unexpected error occurred during analysis of '{}'", d.getActualFilePath());
    +  386  0
                                 LOGGER.debug("", ex);
    +  387  160
                             }
    +  388  
                         }
    -  410  32
                     }
    -  411  16
                 }
    -  412   +  389  304
                     }
    +  390  152
                 }
    +  391  
             }
    -  413  10
             for (AnalysisPhase phase : AnalysisPhase.values()) {
    -  414  9
                 final List<Analyzer> analyzerList = analyzers.get(phase);
    -  415   +  392  80
             for (AnalysisPhase phase : AnalysisPhase.values()) {
    +  393  72
                 final List<Analyzer> analyzerList = analyzers.get(phase);
    +  394  
     
    -  416  9
                 for (Analyzer a : analyzerList) {
    -  417  16
                     closeAnalyzer(a);
    -  418  16
                 }
    -  419   +  395  72
                 for (Analyzer a : analyzerList) {
    +  396  152
                     closeAnalyzer(a);
    +  397  152
                 }
    +  398  
             }
    -  420   +  399  
     
    -  421  1
             final String logFooter = String.format("%n"
    -  422   -
                     + "----------------------------------------------------%n"
    -  423   -
                     + "END ANALYSIS%n"
    -  424   -
                     + "----------------------------------------------------");
    -  425  1
             LOGGER.log(Level.FINE, logFooter);
    -  426  1
             LOGGER.log(Level.INFO, "Analysis Complete");
    -  427  1
         }
    -  428   +  400  8
             LOGGER.debug("\n----------------------------------------------------\nEND ANALYSIS\n----------------------------------------------------");
    +  401  8
             LOGGER.info("Analysis Complete");
    +  402  8
         }
    +  403  
     
    -  429   +  404  
         /**
    -  430   +  405  
          * Initializes the given analyzer.
    -  431   +  406  
          *
    -  432   +  407  
          * @param analyzer the analyzer to initialize
    -  433   +  408  
          * @return the initialized analyzer
    -  434   +  409  
          */
    -  435   +  410  
         protected Analyzer initializeAnalyzer(Analyzer analyzer) {
    -  436   +  411  
             try {
    -  437  16
                 final String msg = String.format("Initializing %s", analyzer.getName());
    -  438  16
                 LOGGER.log(Level.FINE, msg);
    -  439  16
                 analyzer.initialize();
    -  440  0
             } catch (Throwable ex) {
    -  441  0
                 final String msg = String.format("Exception occurred initializing %s.", analyzer.getName());
    -  442  0
                 LOGGER.log(Level.SEVERE, msg);
    -  443  0
                 LOGGER.log(Level.FINE, null, ex);
    -  444   +  412  152
                 LOGGER.debug("Initializing {}", analyzer.getName());
    +  413  152
                 analyzer.initialize();
    +  414  0
             } catch (Throwable ex) {
    +  415  0
                 LOGGER.error("Exception occurred initializing {}.", analyzer.getName());
    +  416  0
                 LOGGER.debug("", ex);
    +  417  
                 try {
    -  445  0
                     analyzer.close();
    -  446  0
                 } catch (Throwable ex1) {
    -  447  0
                     LOGGER.log(Level.FINEST, null, ex1);
    -  448  0
                 }
    -  449  16
             }
    -  450  16
             return analyzer;
    -  451   +  418  0
                     analyzer.close();
    +  419  0
                 } catch (Throwable ex1) {
    +  420  0
                     LOGGER.trace("", ex1);
    +  421  0
                 }
    +  422  152
             }
    +  423  152
             return analyzer;
    +  424  
         }
    -  452   +  425  
     
    -  453   +  426  
         /**
    -  454   +  427  
          * Closes the given analyzer.
    -  455   +  428  
          *
    -  456   +  429  
          * @param analyzer the analyzer to close
    -  457   +  430  
          */
    -  458   +  431  
         protected void closeAnalyzer(Analyzer analyzer) {
    -  459  16
             final String msg = String.format("Closing Analyzer '%s'", analyzer.getName());
    -  460  16
             LOGGER.log(Level.FINE, msg);
    -  461   +  432  152
             LOGGER.debug("Closing Analyzer '{}'", analyzer.getName());
    +  433  
             try {
    -  462  16
                 analyzer.close();
    -  463  0
             } catch (Throwable ex) {
    -  464  0
                 LOGGER.log(Level.FINEST, null, ex);
    -  465  16
             }
    -  466  16
         }
    -  467   +  434  152
                 analyzer.close();
    +  435  0
             } catch (Throwable ex) {
    +  436  0
                 LOGGER.trace("", ex);
    +  437  152
             }
    +  438  152
         }
    +  439  
     
    -  468   +  440  
         /**
    -  469   +  441  
          * Cycles through the cached web data sources and calls update on all of them.
    -  470   +  442  
          */
    -  471   +  443  
         public void doUpdates() {
    -  472  0
             LOGGER.info("Checking for updates");
    -  473  0
             final UpdateService service = new UpdateService(serviceClassLoader);
    -  474  0
             final Iterator<CachedWebDataSource> iterator = service.getDataSources();
    -  475  0
             while (iterator.hasNext()) {
    -  476  0
                 final CachedWebDataSource source = iterator.next();
    -  477   +  444  0
             LOGGER.info("Checking for updates");
    +  445  0
             final UpdateService service = new UpdateService(serviceClassLoader);
    +  446  0
             final Iterator<CachedWebDataSource> iterator = service.getDataSources();
    +  447  0
             while (iterator.hasNext()) {
    +  448  0
                 final CachedWebDataSource source = iterator.next();
    +  449  
                 try {
    -  478  0
                     source.update();
    -  479  0
                 } catch (UpdateException ex) {
    -  480  0
                     LOGGER.log(Level.WARNING,
    -  481   +  450  0
                     source.update();
    +  451  0
                 } catch (UpdateException ex) {
    +  452  0
                     LOGGER.warn(
    +  453  
                             "Unable to update Cached Web DataSource, using local data instead. Results may not include recent vulnerabilities.");
    -  482  0
                     LOGGER.log(Level.FINE, String.format("Unable to update details for %s", source.getClass().getName()), ex);
    -  483  0
                 }
    -  484  0
             }
    -  485  0
             LOGGER.info("Check for updates complete");
    -  486  0
         }
    -  487   +  454  0
                     LOGGER.debug("Unable to update details for {}", source.getClass().getName(), ex);
    +  455  0
                 }
    +  456  0
             }
    +  457  0
             LOGGER.info("Check for updates complete");
    +  458  0
         }
    +  459  
     
    -  488   +  460  
         /**
    -  489   +  461  
          * Returns a full list of all of the analyzers. This is useful for reporting which analyzers where used.
    -  490   +  462  
          *
    -  491   +  463  
          * @return a list of Analyzers
    -  492   +  464  
          */
    -  493   +  465  
         public List<Analyzer> getAnalyzers() {
    -  494  0
             final List<Analyzer> ret = new ArrayList<Analyzer>();
    -  495  0
             for (AnalysisPhase phase : AnalysisPhase.values()) {
    -  496  0
                 final List<Analyzer> analyzerList = analyzers.get(phase);
    -  497  0
                 ret.addAll(analyzerList);
    -  498   +  466  0
             final List<Analyzer> ret = new ArrayList<Analyzer>();
    +  467  0
             for (AnalysisPhase phase : AnalysisPhase.values()) {
    +  468  0
                 final List<Analyzer> analyzerList = analyzers.get(phase);
    +  469  0
                 ret.addAll(analyzerList);
    +  470  
             }
    -  499  0
             return ret;
    +  471  0
             return ret;
    +  472   +
         }
    +  473   +
     
    +  474   +
         /**
    +  475   +
          * Checks all analyzers to see if an extension is supported.
    +  476   +
          *
    +  477   +
          * @param file a file extension
    +  478   +
          * @return true or false depending on whether or not the file extension is supported
    +  479   +
          */
    +  480   +
         public boolean accept(File file) {
    +  481  6808
             if (file == null) {
    +  482  0
                 return false;
    +  483   +
             }
    +  484  6808
             boolean scan = false;
    +  485  6808
             for (FileTypeAnalyzer a : this.fileTypeAnalyzers) {
    +  486   +
                 /* note, we can't break early on this loop as the analyzers need to know if
    +  487   +
                  they have files to work on prior to initialization */
    +  488  74888
                 scan |= a.accept(file);
    +  489  74888
             }
    +  490  6808
             return scan;
    +  491   +
         }
    +  492   +
     
    +  493   +
         /**
    +  494   +
          * Returns the set of file type analyzers.
    +  495   +
          *
    +  496   +
          * @return the set of file type analyzers
    +  497   +
          */
    +  498   +
         public Set<FileTypeAnalyzer> getFileTypeAnalyzers() {
    +  499  0
             return this.fileTypeAnalyzers;
     500  
         }
     501   @@ -826,84 +837,36 @@  502  
         /**
     503   -
          * Checks all analyzers to see if an extension is supported.
    +
          * Checks the CPE Index to ensure documents exists. If none exist a NoDataException is thrown.
     504  
          *
     505   -
          * @param ext a file extension
    +
          * @throws NoDataException thrown if no data exists in the CPE Index
     506   -
          * @return true or false depending on whether or not the file extension is supported
    +
          * @throws DatabaseException thrown if there is an exception opening the database
     507  
          */
     508   -
         public boolean supportsExtension(String ext) {
    -  509  851
             if (ext == null) {
    -  510  3
                 return false;
    -  511   -
             }
    -  512  848
             boolean scan = false;
    -  513  848
             for (FileTypeAnalyzer a : this.fileTypeAnalyzers) {
    -  514   -
                 /* note, we can't break early on this loop as the analyzers need to know if
    -  515   -
                  they have files to work on prior to initialization */
    -  516  6784
                 scan |= a.supportsExtension(ext);
    -  517  6784
             }
    -  518  848
             return scan;
    -  519   -
         }
    -  520   -
     
    -  521   -
         /**
    -  522   -
          * Returns the set of file type analyzers.
    -  523   -
          *
    -  524   -
          * @return the set of file type analyzers
    -  525   -
          */
    -  526   -
         public Set<FileTypeAnalyzer> getFileTypeAnalyzers() {
    -  527  0
             return this.fileTypeAnalyzers;
    -  528   -
         }
    -  529   -
     
    -  530   -
         /**
    -  531   -
          * Checks the CPE Index to ensure documents exists. If none exist a NoDataException is thrown.
    -  532   -
          *
    -  533   -
          * @throws NoDataException thrown if no data exists in the CPE Index
    -  534   -
          * @throws DatabaseException thrown if there is an exception opening the database
    -  535   -
          */
    -  536  
         private void ensureDataExists() throws NoDataException, DatabaseException {
    -  537  1
             final CveDB cve = new CveDB();
    -  538   +  509  8
             final CveDB cve = new CveDB();
    +  510  
             try {
    -  539  1
                 cve.open();
    -  540  1
                 if (!cve.dataExists()) {
    -  541  0
                     throw new NoDataException("No documents exist");
    -  542   +  511  8
                 cve.open();
    +  512  8
                 if (!cve.dataExists()) {
    +  513  0
                     throw new NoDataException("No documents exist");
    +  514  
                 }
    -  543  0
             } catch (DatabaseException ex) {
    -  544  0
                 throw new NoDataException(ex.getMessage(), ex);
    -  545   +  515  0
             } catch (DatabaseException ex) {
    +  516  0
                 throw new NoDataException(ex.getMessage(), ex);
    +  517  
             } finally {
    -  546  1
                 cve.close();
    -  547  1
             }
    -  548  1
         }
    -  549   +  518  8
                 cve.close();
    +  519  8
             }
    +  520  8
         }
    +  521  
     }
    - + 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 9682be96c..61459a528 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.agent.DependencyCheckScanAgent.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.agent.DependencyCheckScanAgent.html @@ -12,7 +12,7 @@
     
    - +
    Classes in this File Line Coverage Branch Coverage Complexity
    DependencyCheckScanAgent
    0%
    0/245
    0%
    0/112
    1.847
    DependencyCheckScanAgent
    0%
    0/244
    0%
    0/112
    1.847
     
    @@ -62,29 +62,29 @@  22  
     import java.util.List;
     23   -
     import java.util.logging.Level;
    -  24   -
     import java.util.logging.Logger;
    -  25  
     import org.owasp.dependencycheck.Engine;
    -  26   +  24  
     import org.owasp.dependencycheck.data.nvdcve.CveDB;
    -  27   +  25  
     import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
    -  28   +  26  
     import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties;
    -  29   +  27  
     import org.owasp.dependencycheck.dependency.Dependency;
    -  30   +  28  
     import org.owasp.dependencycheck.dependency.Identifier;
    -  31   +  29  
     import org.owasp.dependencycheck.dependency.Vulnerability;
    -  32   +  30  
     import org.owasp.dependencycheck.exception.ScanAgentException;
    -  33   +  31  
     import org.owasp.dependencycheck.reporting.ReportGenerator;
    -  34   +  32  
     import org.owasp.dependencycheck.utils.Settings;
    +  33   +
     import org.slf4j.Logger;
    +  34   +
     import org.slf4j.LoggerFactory;
     35  
     
     36   @@ -153,7 +153,7 @@
          * Logger for use throughout the class.
     69  
          */
    -  70  0
         private static final Logger LOGGER = Logger.getLogger(DependencyCheckScanAgent.class.getName());
    +  70  0
         private static final Logger LOGGER = LoggerFactory.getLogger(DependencyCheckScanAgent.class);
     71  
         /**
     72   @@ -1618,7 +1618,7 @@  861  0
                 cve.open();
     862  0
                 prop = cve.getDatabaseProperties();
     863  0
             } catch (DatabaseException ex) {
    -  864  0
                 LOGGER.log(Level.FINE, "Unable to retrieve DB Properties", ex);
    +  864  0
                 LOGGER.debug("Unable to retrieve DB Properties", ex);
     865  
             } finally {
     866  0
                 if (cve != null) {
    @@ -1632,15 +1632,15 @@
             try {
     872  0
                 r.generateReports(outDirectory.getCanonicalPath(), this.reportFormat.name());
     873  0
             } catch (IOException ex) {
    -  874  0
                 LOGGER.log(Level.SEVERE,
    +  874  0
                 LOGGER.error(
     875  
                         "Unexpected exception occurred during analysis; please see the verbose error log for more details.");
    -  876  0
                 LOGGER.log(Level.FINE, null, ex);
    +  876  0
                 LOGGER.debug("", ex);
     877  0
             } catch (Throwable ex) {
    -  878  0
                 LOGGER.log(Level.SEVERE,
    +  878  0
                 LOGGER.error(
     879  
                         "Unexpected exception occurred during analysis; please see the verbose error log for more details.");
    -  880  0
                 LOGGER.log(Level.FINE, null, ex);
    +  880  0
                 LOGGER.debug("", ex);
     881  0
             }
     882  0
         }
     883   @@ -1785,10 +1785,10 @@  982  
                 }
     983  0
             } catch (DatabaseException ex) {
    -  984  0
                 LOGGER.log(Level.SEVERE,
    +  984  0
                 LOGGER.error(
     985  
                         "Unable to connect to the dependency-check database; analysis has stopped");
    -  986  0
                 LOGGER.log(Level.FINE, "", ex);
    +  986  0
                 LOGGER.debug("", ex);
     987  
             } finally {
     988  0
                 Settings.cleanup(true);
    @@ -1895,21 +1895,20 @@
                 }
     1059  0
             }
     1060  0
             if (summary.length() > 0) {
    -  1061  0
                 final String msg = String.format("%n%n"
    +  1061  0
                 LOGGER.warn("\n\nOne or more dependencies were identified with known vulnerabilities:\n\n{}\n\n"
     1062   -
                         + "One or more dependencies were identified with known vulnerabilities:%n%n%s"
    +
                         + "See the dependency-check report for more details.\n\n",
     1063   -
                         + "%n%nSee the dependency-check report for more details.%n%n", summary.toString());
    -  1064  0
                 LOGGER.log(Level.WARNING, msg);
    -  1065   +
                         summary.toString());
    +  1064  
             }
    -  1066  0
         }
    -  1067   +  1065  0
         }
    +  1066  
     
    -  1068   +  1067  
     }
    - + 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 9ae731b20..a6c7d2fd8 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  78
     public abstract class AbstractAnalyzer implements Analyzer {
    +  24  856
     public abstract class AbstractAnalyzer implements Analyzer {
     25  
     
     26   @@ -82,7 +82,7 @@
         public void initialize() throws Exception {
     33  
             //do nothing
    -  34  10
         }
    +  34  80
         }
     35  
     
     36   @@ -101,11 +101,11 @@
         public void close() throws Exception {
     43  
             //do nothing
    -  44  21
         }
    +  44  304
         }
     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 17e50f989..ec490361c 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AbstractFileTypeAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AbstractFileTypeAnalyzer.html @@ -12,7 +12,7 @@
     
    - +
    Classes in this File Line Coverage Branch Coverage Complexity
    AbstractFileTypeAnalyzer
    74%
    32/43
    80%
    8/10
    1.571
    AbstractFileTypeAnalyzer
    82%
    32/39
    80%
    8/10
    1.429
     
    @@ -56,400 +56,376 @@  19  
     
     20   -
     import java.util.Collections;
    -  21   -
     import java.util.HashSet;
    -  22   -
     import java.util.Set;
    -  23   -
     import java.util.logging.Level;
    -  24   -
     import java.util.logging.Logger;
    -  25  
     import org.owasp.dependencycheck.Engine;
    -  26   +  21  
     import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
    -  27   +  22  
     import org.owasp.dependencycheck.dependency.Dependency;
    -  28   +  23  
     import org.owasp.dependencycheck.utils.InvalidSettingException;
    -  29   +  24  
     import org.owasp.dependencycheck.utils.Settings;
    +  25   +
     import org.slf4j.Logger;
    +  26   +
     import org.slf4j.LoggerFactory;
    +  27   +
     
    +  28   +
     import java.io.File;
    +  29   +
     import java.io.FileFilter;
     30   -
     
    +
     import java.util.Collections;
     31   -
     /**
    +
     import java.util.HashSet;
     32   -
      * The base FileTypeAnalyzer that all analyzers that have specific file types they analyze should extend.
    +
     import java.util.Set;
     33   -
      *
    +
     
     34   -
      * @author Jeremy Long
    +
     /**
     35   -
      */
    +
      * The base FileTypeAnalyzer that all analyzers that have specific file types they analyze should extend.
     36   -
     public abstract class AbstractFileTypeAnalyzer extends AbstractAnalyzer implements FileTypeAnalyzer {
    +
      *
     37   -
     
    +
      * @author Jeremy Long
     38   -
         //<editor-fold defaultstate="collapsed" desc="Constructor">
    +
      */
     39   -
         /**
    +
     public abstract class AbstractFileTypeAnalyzer extends AbstractAnalyzer implements FileTypeAnalyzer {
     40   -
          * Base constructor that all children must call. This checks the configuration to determine if the analyzer is
    +
     
     41   -
          * enabled.
    +
         //<editor-fold defaultstate="collapsed" desc="Constructor">
     42   +
         /**
    +  43   +
          * Base constructor that all children must call. This checks the configuration to determine if the analyzer is enabled.
    +  44  
          */
    -  43  47
         public AbstractFileTypeAnalyzer() {
    -  44  47
             reset();
    -  45  47
         }
    -  46   -
     //</editor-fold>
    -  47   -
     
    +  45  560
         public AbstractFileTypeAnalyzer() {
    +  46  560
             reset();
    +  47  560
         }
     48   -
         //<editor-fold defaultstate="collapsed" desc="Field definitions">
    +
     //</editor-fold>
     49   -
         /**
    +
     
     50   -
          * The logger.
    +
         //<editor-fold defaultstate="collapsed" desc="Field definitions">
     51   -
          */
    -  52  1
         private static final Logger LOGGER = Logger.getLogger(AbstractFileTypeAnalyzer.class.getName());
    +
         /**
    +  52   +
          * The logger.
     53   -
         /**
    -  54   -
          * Whether the file type analyzer detected any files it needs to analyze.
    +
          */
    +  54  8
         private static final Logger LOGGER = LoggerFactory.getLogger(AbstractFileTypeAnalyzer.class);
     55   -
          */
    -  56  47
         private boolean filesMatched = false;
    +
         /**
    +  56   +
          * Whether the file type analyzer detected any files it needs to analyze.
     57   -
     
    -  58   -
         /**
    +
          */
    +  58  560
         private boolean filesMatched = false;
     59   -
          * Get the value of filesMatched. A flag indicating whether the scan included any file types this analyzer supports.
    +
     
     60   -
          *
    +
         /**
     61   -
          * @return the value of filesMatched
    +
          * Get the value of filesMatched. A flag indicating whether the scan included any file types this analyzer supports.
     62   -
          */
    +
          *
     63   -
         protected boolean isFilesMatched() {
    -  64  0
             return filesMatched;
    +
          * @return the value of filesMatched
    +  64   +
          */
     65   -
         }
    -  66   -
     
    +
         protected boolean isFilesMatched() {
    +  66  0
             return filesMatched;
     67   -
         /**
    +
         }
     68   -
          * Set the value of filesMatched. A flag indicating whether the scan included any file types this analyzer supports.
    +
     
     69   -
          *
    +
         /**
     70   -
          * @param filesMatched new value of filesMatched
    +
          * Set the value of filesMatched. A flag indicating whether the scan included any file types this analyzer supports.
     71   -
          */
    +
          *
     72   +
          * @param filesMatched new value of filesMatched
    +  73   +
          */
    +  74  
         protected void setFilesMatched(boolean filesMatched) {
    -  73  13
             this.filesMatched = filesMatched;
    -  74  13
         }
    -  75   -
     
    -  76   -
         /**
    +  75  208
             this.filesMatched = filesMatched;
    +  76  208
         }
     77   -
          * A flag indicating whether or not the analyzer is enabled.
    +
     
     78   -
          */
    -  79  47
         private boolean enabled = true;
    +
         /**
    +  79   +
          * A flag indicating whether or not the analyzer is enabled.
     80   -
     
    -  81   -
         /**
    +
          */
    +  81  560
         private boolean enabled = true;
     82   -
          * Get the value of enabled.
    +
     
     83   -
          *
    +
         /**
     84   -
          * @return the value of enabled
    +
          * Get the value of enabled.
     85   -
          */
    +
          *
     86   -
         public boolean isEnabled() {
    -  87  0
             return enabled;
    +
          * @return the value of enabled
    +  87   +
          */
     88   -
         }
    -  89   -
     
    +
         public boolean isEnabled() {
    +  89  0
             return enabled;
     90   -
         /**
    +
         }
     91   -
          * Set the value of enabled.
    +
     
     92   -
          *
    +
         /**
     93   -
          * @param enabled new value of enabled
    +
          * Set the value of enabled.
     94   -
          */
    +
          *
     95   +
          * @param enabled new value of enabled
    +  96   +
          */
    +  97  
         public void setEnabled(boolean enabled) {
    -  96  4
             this.enabled = enabled;
    -  97  4
         }
    -  98   -
     //</editor-fold>
    -  99   -
     
    +  98  32
             this.enabled = enabled;
    +  99  32
         }
     100   -
         //<editor-fold defaultstate="collapsed" desc="Abstract methods children must implement">
    +
     //</editor-fold>
     101   -
         /**
    +
     
     102   -
          * <p>
    +
         //<editor-fold defaultstate="collapsed" desc="Abstract methods children must implement">
     103   -
          * Returns a list of supported file extensions. An example would be an analyzer that inspected java jar files. The
    +
         /**
     104   -
          * getSupportedExtensions function would return a set with a single element "jar".</p>
    +
          * <p>
     105   -
          *
    +
          * Returns the {@link java.io.FileFilter} used to determine which files are to be analyzed. An example would be an analyzer
     106   -
          * <p>
    +
          * that inspected Java jar files. Implementors may use {@link org.owasp.dependencycheck.utils.FileFilterBuilder}.</p>
     107   -
          * <b>Note:</b> when implementing this the extensions returned MUST be lowercase.</p>
    +
          *
     108   -
          *
    +
          * @return the file filter used to determine which files are to be analyzed
     109   -
          * @return The file extensions supported by this analyzer.
    +
          * <p/>
     110   -
          *
    +
          * <p>
     111   -
          * <p>
    +
          * If the analyzer returns null it will not cause additional files to be analyzed, but will be executed against every file
     112   -
          * If the analyzer returns null it will not cause additional files to be analyzed but will be executed against every
    +
          * loaded.</p>
     113   -
          * file loaded</p>
    +
          */
     114   -
          */
    +
         protected abstract FileFilter getFileFilter();
     115   -
         protected abstract Set<String> getSupportedExtensions();
    +
     
     116   -
     
    +
         /**
     117   -
         /**
    -  118  
          * Initializes the file type analyzer.
    +  118   +
          *
     119   -
          *
    +
          * @throws Exception thrown if there is an exception during initialization
     120   -
          * @throws Exception thrown if there is an exception during initialization
    +
          */
     121   -
          */
    -  122  
         protected abstract void initializeFileTypeAnalyzer() throws Exception;
    +  122   +
     
     123   -
     
    +
         /**
     124   -
         /**
    +
          * Analyzes a given dependency. If the dependency is an archive, such as a WAR or EAR, the contents are extracted, scanned,
     125   -
          * Analyzes a given dependency. If the dependency is an archive, such as a WAR or EAR, the contents are extracted,
    +
          * and added to the list of dependencies within the engine.
     126   -
          * scanned, and added to the list of dependencies within the engine.
    +
          *
     127   -
          *
    +
          * @param dependency the dependency to analyze
     128   -
          * @param dependency the dependency to analyze
    +
          * @param engine the engine scanning
     129   -
          * @param engine the engine scanning
    +
          * @throws AnalysisException thrown if there is an analysis exception
     130   -
          * @throws AnalysisException thrown if there is an analysis exception
    +
          */
     131   -
          */
    -  132  
         protected abstract void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException;
    +  132   +
     
     133   -
     
    +
         /**
     134   -
         /**
    +
          * <p>
     135   -
          * <p>
    -  136  
          * Returns the setting key to determine if the analyzer is enabled.</p>
    +  136   +
          *
     137   -
          *
    -  138  
          * @return the key for the analyzer's enabled property
    +  138   +
          */
     139   -
          */
    -  140  
         protected abstract String getAnalyzerEnabledSettingKey();
    +  140   +
     
     141   -
     
    +
     //</editor-fold>
     142   -
     //</editor-fold>
    -  143  
         //<editor-fold defaultstate="collapsed" desc="Final implementations for the Analyzer interface">
    +  143   +
         /**
     144   -
         /**
    -  145  
          * Initializes the analyzer.
    +  145   +
          *
     146   -
          *
    -  147  
          * @throws Exception thrown if there is an exception during initialization
    +  147   +
          */
     148   -
          */
    +
         @Override
     149   -
         @Override
    -  150  
         public final void initialize() throws Exception {
    -  151  26
             if (filesMatched) {
    -  152  20
                 initializeFileTypeAnalyzer();
    -  153   +  150  368
             if (filesMatched) {
    +  151  264
                 initializeFileTypeAnalyzer();
    +  152  
             } else {
    -  154  6
                 enabled = false;
    -  155   +  153  104
                 enabled = false;
    +  154  
             }
    -  156  26
         }
    +  155  368
         }
    +  156   +
     
     157   -
     
    +
         /**
     158   -
         /**
    -  159  
          * Resets the enabled flag on the analyzer.
    +  159   +
          */
     160   -
          */
    +
         @Override
     161   -
         @Override
    -  162  
         public final void reset() {
    -  163  47
             final String key = getAnalyzerEnabledSettingKey();
    -  164   +  162  560
             final String key = getAnalyzerEnabledSettingKey();
    +  163  
             try {
    -  165  47
                 enabled = Settings.getBoolean(key, true);
    -  166  0
             } catch (InvalidSettingException ex) {
    -  167  0
                 String msg = String.format("Invalid setting for property '%s'", key);
    -  168  0
                 LOGGER.log(Level.WARNING, msg);
    -  169  0
                 LOGGER.log(Level.FINE, "", ex);
    -  170  0
                 msg = String.format("%s has been disabled", getName());
    -  171  0
                 LOGGER.log(Level.WARNING, msg);
    -  172  47
             }
    -  173  47
         }
    +  164  560
                 enabled = Settings.getBoolean(key, true);
    +  165  0
             } catch (InvalidSettingException ex) {
    +  166  0
                 LOGGER.warn("Invalid setting for property '{}'", key);
    +  167  0
                 LOGGER.debug("", ex);
    +  168  0
                 LOGGER.warn("{} has been disabled", getName());
    +  169  560
             }
    +  170  560
         }
    +  171   +
     
    +  172   +
         /**
    +  173   +
          * Analyzes a given dependency. If the dependency is an archive, such as a WAR or EAR, the contents are extracted, scanned,
     174   -
     
    +
          * and added to the list of dependencies within the engine.
     175   -
         /**
    +
          *
     176   -
          * Analyzes a given dependency. If the dependency is an archive, such as a WAR or EAR, the contents are extracted,
    -  177   -
          * scanned, and added to the list of dependencies within the engine.
    -  178   -
          *
    -  179  
          * @param dependency the dependency to analyze
    -  180   +  177  
          * @param engine the engine scanning
    -  181   +  178  
          * @throws AnalysisException thrown if there is an analysis exception
    -  182   +  179  
          */
    -  183   +  180  
         @Override
    -  184   +  181  
         public final void analyze(Dependency dependency, Engine engine) throws AnalysisException {
    -  185  17
             if (enabled) {
    -  186  17
                 analyzeFileType(dependency, engine);
    +  182  200
             if (enabled) {
    +  183  200
                 analyzeFileType(dependency, engine);
    +  184   +
             }
    +  185  192
         }
    +  186   +
     
     187   -
             }
    -  188  16
         }
    -  189   -
     
    -  190   -
         /**
    -  191   -
          * Returns whether or not this analyzer can process the given extension.
    -  192   -
          *
    -  193   -
          * @param extension the file extension to test for support.
    -  194   -
          * @return whether or not the specified file extension is supported by this analyzer.
    -  195   -
          */
    -  196  
         @Override
    +  188   +
         public boolean accept(File pathname) {
    +  189  75232
             final FileFilter filter = getFileFilter();
    +  190  75232
             boolean accepted = false;
    +  191  75232
             if (null == filter) {
    +  192  0
                 LOGGER.error("The '{}' analyzer is misconfigured and does not have a file filter; it will be disabled", getName());
    +  193  75232
             } else if (enabled) {
    +  194  61472
                 accepted = filter.accept(pathname);
    +  195  61472
                 if (accepted) {
    +  196  224
                     filesMatched = true;
     197   -
         public final boolean supportsExtension(String extension) {
    -  198  6815
             if (!enabled) {
    -  199  1708
                 return false;
    -  200   -
             }
    -  201  5107
             final Set<String> ext = getSupportedExtensions();
    -  202  5107
             if (ext == null) {
    -  203  0
                 final String msg = String.format("The '%s' analyzer is misconfigured and does not have any file extensions;"
    -  204   -
                         + " it will be disabled", getName());
    -  205  0
                 LOGGER.log(Level.SEVERE, msg);
    -  206  0
                 return false;
    -  207   -
             } else {
    -  208  5107
                 final boolean match = ext.contains(extension);
    -  209  5107
                 if (match) {
    -  210  22
                     filesMatched = match;
    -  211  
                 }
    -  212  5107
                 return match;
    -  213   +  198  
             }
    -  214   +  199  75232
             return accepted;
    +  200  
         }
    -  215   -
     //</editor-fold>
    -  216   +  201  
     
    -  217   +  202   +
         //</editor-fold>
    +  203  
         //<editor-fold defaultstate="collapsed" desc="Static utility methods">
    -  218   +  204  
         /**
    -  219   +  205  
          * <p>
    -  220   -
          * Utility method to help in the creation of the extensions set. This constructs a new Set that can be used in a
    -  221   -
          * final static declaration.</p>
    -  222   -
          *
    -  223   +  206   +
          * Utility method to help in the creation of the extensions set. This constructs a new Set that can be used in a final static
    +  207   +
          * declaration.</p>
    +  208   +
          * <p/>
    +  209  
          * <p>
    -  224   +  210  
          * This implementation was copied from
    -  225   +  211  
          * http://stackoverflow.com/questions/2041778/initialize-java-hashset-values-by-construction</p>
    -  226   +  212  
          *
    -  227   +  213  
          * @param strings a list of strings to add to the set.
    -  228   +  214  
          * @return a Set of strings.
    -  229   +  215  
          */
    -  230   +  216  
         protected static Set<String> newHashSet(String... strings) {
    -  231  13
             final Set<String> set = new HashSet<String>();
    -  232   -
     
    -  233  13
             Collections.addAll(set, strings);
    -  234  13
             return set;
    -  235   +  217  40
             final Set<String> set = new HashSet<String>();
    +  218  40
             Collections.addAll(set, strings);
    +  219  40
             return set;
    +  220  
         }
    -  236   +  221   +
     
    +  222  
     //</editor-fold>
    -  237   +  223  
     }
    - + 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 9d5e35129..7f8d06d6a 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%
    49/61
    71%
    10/14
    3.833
    AbstractSuppressionAnalyzer
    80%
    48/60
    71%
    10/14
    3.833
     
    @@ -70,25 +70,25 @@  26  
     import java.util.Set;
     27   -
     import java.util.logging.Level;
    -  28   -
     import java.util.logging.Logger;
    -  29  
     import java.util.regex.Pattern;
    -  30   +  28  
     import org.owasp.dependencycheck.suppression.SuppressionParseException;
    -  31   +  29  
     import org.owasp.dependencycheck.suppression.SuppressionParser;
    -  32   +  30  
     import org.owasp.dependencycheck.suppression.SuppressionRule;
    -  33   +  31  
     import org.owasp.dependencycheck.utils.DownloadFailedException;
    -  34   +  32  
     import org.owasp.dependencycheck.utils.Downloader;
    -  35   +  33  
     import org.owasp.dependencycheck.utils.FileUtils;
    -  36   +  34  
     import org.owasp.dependencycheck.utils.Settings;
    +  35   +
     import org.slf4j.Logger;
    +  36   +
     import org.slf4j.LoggerFactory;
     37  
     
     38   @@ -101,7 +101,7 @@
      * @author Jeremy Long
     42  
      */
    -  43  8
     public abstract class AbstractSuppressionAnalyzer extends AbstractAnalyzer {
    +  43  80
     public abstract class AbstractSuppressionAnalyzer extends AbstractAnalyzer {
     44  
     
     45   @@ -110,7 +110,7 @@
          * The Logger for use throughout the class
     47  
          */
    -  48  1
         private static final Logger LOGGER = Logger.getLogger(AbstractSuppressionAnalyzer.class.getName());
    +  48  8
         private static final Logger LOGGER = LoggerFactory.getLogger(AbstractSuppressionAnalyzer.class);
     49  
     
     50   @@ -127,7 +127,7 @@
          */
     56  
         public Set<String> getSupportedExtensions() {
    -  57  1
             return null;
    +  57  8
             return null;
     58  
         }
     59   @@ -148,9 +148,9 @@
         @Override
     67  
         public void initialize() throws Exception {
    -  68  5
             super.initialize();
    -  69  5
             loadSuppressionData();
    -  70  4
         }
    +  68  40
             super.initialize();
    +  69  40
             loadSuppressionData();
    +  70  32
         }
     71  
     
     72   @@ -175,7 +175,7 @@
          */
     82  
         public List<SuppressionRule> getRules() {
    -  83  14
             return rules;
    +  83  112
             return rules;
     84  
         }
     85   @@ -208,46 +208,46 @@
          */
     100  
         private void loadSuppressionData() throws SuppressionParseException {
    -  101  5
             final SuppressionParser parser = new SuppressionParser();
    -  102  5
             File file = null;
    +  101  40
             final SuppressionParser parser = new SuppressionParser();
    +  102  40
             File file = null;
     103  
             try {
    -  104  5
                 rules = parser.parseSuppressionRules(this.getClass().getClassLoader().getResourceAsStream("dependencycheck-base-suppression.xml"));
    +  104  40
                 rules = parser.parseSuppressionRules(this.getClass().getClassLoader().getResourceAsStream("dependencycheck-base-suppression.xml"));
     105  0
             } catch (SuppressionParseException ex) {
    -  106  0
                 LOGGER.log(Level.FINE, "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;
    +  106  0
                 LOGGER.debug("Unable to parse the base suppression data file", ex);
    +  107  40
             }
    +  108  40
             final String suppressionFilePath = Settings.getString(Settings.KEYS.SUPPRESSION_FILE);
    +  109  40
             if (suppressionFilePath == null) {
    +  110  16
                 return;
     111  
             }
    -  112  3
             boolean deleteTempFile = false;
    +  112  24
             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);
    +  114  24
                 final Pattern uriRx = Pattern.compile("^(https?|file)\\:.*", Pattern.CASE_INSENSITIVE);
    +  115  24
                 if (uriRx.matcher(suppressionFilePath).matches()) {
    +  116  8
                     deleteTempFile = true;
    +  117  8
                     file = FileUtils.getTempFile("suppression", "xml");
    +  118  8
                     final URL url = new URL(suppressionFilePath);
     119  
                     try {
    -  120  1
                         Downloader.fetchFile(url, file, false);
    +  120  8
                         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");
    +  123  8
                     }
    +  124  8
                 } else {
    +  125  16
                     file = new File(suppressionFilePath);
    +  126  16
                     if (!file.exists()) {
    +  127  16
                         final InputStream suppressionsFromClasspath = this.getClass().getClassLoader().getResourceAsStream(suppressionFilePath);
    +  128  16
                         if (suppressionsFromClasspath != null) {
    +  129  8
                             deleteTempFile = true;
    +  130  8
                             file = FileUtils.getTempFile("suppression", "xml");
     131  
                             try {
    -  132  1
                                 org.apache.commons.io.FileUtils.copyInputStreamToFile(suppressionsFromClasspath, file);
    +  132  8
                                 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
                             }
    +  135  8
                             }
     136  
                         }
     137   @@ -256,64 +256,63 @@
                 }
     139  
     
    -  140  3
                 if (file != null) {
    +  140  24
                 if (file != null) {
     141  
                     try {
     142  
                         //rules = parser.parseSuppressionRules(file);
    -  143  3
                         rules.addAll(parser.parseSuppressionRules(file));
    -  144  2
                         LOGGER.log(Level.FINE, rules.size() + " suppression rules were loaded.");
    -  145  1
                     } catch (SuppressionParseException ex) {
    -  146  1
                         final String msg = String.format("Unable to parse suppression xml file '%s'", file.getPath());
    -  147  1
                         LOGGER.log(Level.WARNING, msg);
    -  148  1
                         LOGGER.log(Level.WARNING, ex.getMessage());
    -  149  1
                         LOGGER.log(Level.FINE, "", ex);
    -  150  1
                         throw ex;
    -  151  2
                     }
    -  152   +  143  24
                         rules.addAll(parser.parseSuppressionRules(file));
    +  144  16
                         LOGGER.debug("{} suppression rules were loaded.", rules.size());
    +  145  8
                     } catch (SuppressionParseException ex) {
    +  146  8
                         LOGGER.warn("Unable to parse suppression xml file '{}'", file.getPath());
    +  147  8
                         LOGGER.warn(ex.getMessage());
    +  148  8
                         LOGGER.debug("", ex);
    +  149  8
                         throw ex;
    +  150  16
                     }
    +  151  
                 }
    -  153  0
             } catch (DownloadFailedException ex) {
    -  154  0
                 throwSuppressionParseException("Unable to fetch the configured suppression file", ex);
    -  155  0
             } catch (MalformedURLException ex) {
    -  156  0
                 throwSuppressionParseException("Configured suppression file has an invalid URL", ex);
    -  157  1
             } catch (IOException ex) {
    -  158  1
                 throwSuppressionParseException("Unable to create temp file for suppressions", ex);
    -  159   +  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  8
             } catch (IOException ex) {
    +  157  8
                 throwSuppressionParseException("Unable to create temp file for suppressions", ex);
    +  158  
             } finally {
    -  160  3
                 if (deleteTempFile && file != null) {
    -  161  2
                     FileUtils.delete(file);
    -  162   +  159  24
                 if (deleteTempFile && file != null) {
    +  160  16
                     FileUtils.delete(file);
    +  161  
                 }
    -  163   +  162  
             }
    -  164  2
         }
    -  165   +  163  16
         }
    +  164  
     
    -  166   +  165  
         /**
    -  167   +  166  
          * Utility method to throw parse exceptions.
    -  168   +  167  
          *
    -  169   +  168  
          * @param message the exception message
    -  170   +  169  
          * @param exception the cause of the exception
    -  171   +  170  
          * @throws SuppressionParseException throws the generated SuppressionParseException
    -  172   +  171  
          */
    -  173   +  172  
         private void throwSuppressionParseException(String message, Exception exception) throws SuppressionParseException {
    -  174  1
             LOGGER.log(Level.WARNING, message);
    -  175  1
             LOGGER.log(Level.FINE, "", exception);
    -  176  1
             throw new SuppressionParseException(message, exception);
    -  177   +  173  8
             LOGGER.warn(message);
    +  174  8
             LOGGER.debug("", exception);
    +  175  8
             throw new SuppressionParseException(message, exception);
    +  176  
         }
    -  178   +  177  
     }
    - + 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 3f5da8412..9323d9b2f 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  14
     public enum AnalysisPhase {
    +  25  120
     public enum AnalysisPhase {
     26  
     
     27   @@ -74,67 +74,67 @@
          * Initialization phase.
     29  
          */
    -  30  1
         INITIAL,
    +  30  8
         INITIAL,
     31  
         /**
     32  
          * Information collection phase.
     33  
          */
    -  34  1
         INFORMATION_COLLECTION,
    +  34  8
         INFORMATION_COLLECTION,
     35  
         /**
     36  
          * Pre identifier analysis phase.
     37  
          */
    -  38  1
         PRE_IDENTIFIER_ANALYSIS,
    +  38  8
         PRE_IDENTIFIER_ANALYSIS,
     39  
         /**
     40  
          * Identifier analysis phase.
     41  
          */
    -  42  1
         IDENTIFIER_ANALYSIS,
    +  42  8
         IDENTIFIER_ANALYSIS,
     43  
         /**
     44  
          * Post identifier analysis phase.
     45  
          */
    -  46  1
         POST_IDENTIFIER_ANALYSIS,
    +  46  8
         POST_IDENTIFIER_ANALYSIS,
     47  
         /**
     48  
          * Pre finding analysis phase.
     49  
          */
    -  50  1
         PRE_FINDING_ANALYSIS,
    +  50  8
         PRE_FINDING_ANALYSIS,
     51  
         /**
     52  
          * Finding analysis phase.
     53  
          */
    -  54  1
         FINDING_ANALYSIS,
    +  54  8
         FINDING_ANALYSIS,
     55  
         /**
     56  
          * Post analysis phase.
     57  
          */
    -  58  1
         POST_FINDING_ANALYSIS,
    +  58  8
         POST_FINDING_ANALYSIS,
     59  
         /**
     60  
          * The final analysis phase.
     61  
          */
    -  62  1
         FINAL
    +  62  8
         FINAL
     63  
     }
    - + 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 d3884612d..1ee337631 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 212d2956e..c87636f5b 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AnalyzerService.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AnalyzerService.html @@ -97,9 +97,9 @@
          * @param classLoader the ClassLoader to use when dynamically loading Analyzer and Update services
     40  
          */
    -  41  2
         public AnalyzerService(ClassLoader classLoader) {
    -  42  2
             loader = ServiceLoader.load(Analyzer.class, classLoader);
    -  43  2
         }
    +  41  24
         public AnalyzerService(ClassLoader classLoader) {
    +  42  24
             loader = ServiceLoader.load(Analyzer.class, classLoader);
    +  43  24
         }
     44  
     
     45   @@ -114,13 +114,13 @@
          */
     50  
         public Iterator<Analyzer> getAnalyzers() {
    -  51  2
             return loader.iterator();
    +  51  24
             return loader.iterator();
     52  
         }
     53  
     }
    - + 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 7b4ebb808..e578f229d 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
    31%
    67/216
    22%
    20/90
    7.25
    ArchiveAnalyzer
    31%
    67/211
    22%
    20/90
    7.25
     
    @@ -62,31 +62,31 @@  22  
     import java.io.File;
     23   -
     import java.io.FileInputStream;
    +
     import java.io.FileFilter;
     24   -
     import java.io.FileNotFoundException;
    +
     import java.io.FileInputStream;
     25   -
     import java.io.FileOutputStream;
    +
     import java.io.FileNotFoundException;
     26   -
     import java.io.IOException;
    +
     import java.io.FileOutputStream;
     27   -
     import java.util.ArrayList;
    +
     import java.io.IOException;
     28   -
     import java.util.Arrays;
    +
     import java.util.ArrayList;
     29   -
     import java.util.Collections;
    +
     import java.util.Arrays;
     30   -
     import java.util.Enumeration;
    +
     import java.util.Collections;
     31   -
     import java.util.HashSet;
    +
     import java.util.Enumeration;
     32   -
     import java.util.List;
    +
     import java.util.HashSet;
     33   -
     import java.util.Set;
    +
     import java.util.List;
     34   -
     import java.util.logging.Level;
    +
     import java.util.Set;
     35   -
     import java.util.logging.Logger;
    +
     
     36  
     import org.apache.commons.compress.archivers.ArchiveEntry;
     37   @@ -114,695 +114,704 @@  48  
     import org.owasp.dependencycheck.dependency.Dependency;
     49   -
     import org.owasp.dependencycheck.utils.FileUtils;
    +
     import org.owasp.dependencycheck.utils.FileFilterBuilder;
     50   -
     import org.owasp.dependencycheck.utils.Settings;
    +
     import org.owasp.dependencycheck.utils.FileUtils;
     51   -
     
    +
     import org.owasp.dependencycheck.utils.Settings;
     52   -
     /**
    +
     import org.slf4j.Logger;
     53   -
      * <p>
    +
     import org.slf4j.LoggerFactory;
     54   -
      * An analyzer that extracts files from archives and ensures any supported files contained within the archive are added
    +
     
     55   -
      * to the dependency list.</p>
    +
     /**
     56   -
      *
    +
      * <p>
     57   -
      * @author Jeremy Long
    +
      * An analyzer that extracts files from archives and ensures any supported files contained within the archive are added to the
     58   -
      */
    -  59  2
     public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
    +
      * dependency list.</p>
    +  59   +
      *
     60   -
     
    +
      * @author Jeremy Long
     61   -
         /**
    -  62   -
          * The logger.
    +
      */
    +  62  24
     public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
     63   -
          */
    -  64  1
         private static final Logger LOGGER = Logger.getLogger(ArchiveAnalyzer.class.getName());
    +
     
    +  64   +
         /**
     65   -
         /**
    +
          * The logger.
     66   -
          * The buffer size to use when extracting files from the archive.
    -  67  
          */
    +  67  8
         private static final Logger LOGGER = LoggerFactory.getLogger(ArchiveAnalyzer.class);
     68   -
         private static final int BUFFER_SIZE = 4096;
    +
         /**
     69   -
         /**
    +
          * The buffer size to use when extracting files from the archive.
     70   -
          * The count of directories created during analysis. This is used for creating temporary directories.
    +
          */
     71   -
          */
    -  72  1
         private static int dirCount = 0;
    +
         private static final int BUFFER_SIZE = 4096;
    +  72   +
         /**
     73   -
         /**
    +
          * The count of directories created during analysis. This is used for creating temporary directories.
     74   -
          * The parent directory for the individual directories per archive.
    -  75  
          */
    -  76  2
         private File tempFileLocation = null;
    +  75  8
         private static int dirCount = 0;
    +  76   +
         /**
     77   -
         /**
    +
          * The parent directory for the individual directories per archive.
     78   -
          * The max scan depth that the analyzer will recursively extract nested archives.
    -  79  
          */
    -  80  1
         private static final int MAX_SCAN_DEPTH = Settings.getInt("archive.scan.depth", 3);
    +  79  24
         private File tempFileLocation = null;
    +  80   +
         /**
     81   -
         /**
    +
          * The max scan depth that the analyzer will recursively extract nested archives.
     82   -
          * Tracks the current scan/extraction depth for nested archives.
    -  83  
          */
    -  84  2
         private int scanDepth = 0;
    +  83  8
         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   -
         //<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer">
    -  87   -
         /**
    +
          */
    +  87  24
         private int scanDepth = 0;
     88   -
          * The name of the analyzer.
    +
     
     89   -
          */
    +
         //<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer">
     90   -
         private static final String ANALYZER_NAME = "Archive Analyzer";
    +
         /**
     91   -
         /**
    +
          * The name of the analyzer.
     92   -
          * The phase that this analyzer is intended to run in.
    +
          */
     93   -
          */
    -  94  1
         private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INITIAL;
    +
         private static final String ANALYZER_NAME = "Archive Analyzer";
    +  94   +
         /**
     95   -
         /**
    +
          * The phase that this analyzer is intended to run in.
     96   -
          * The set of things we can handle with Zip methods
    -  97  
          */
    -  98  1
         private static final Set<String> ZIPPABLES = newHashSet("zip", "ear", "war", "jar", "sar", "apk", "nupkg");
    +  97  8
         private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INITIAL;
    +  98   +
         /**
     99   -
         /**
    +
          * The set of things we can handle with Zip methods
     100   -
          * The set of file extensions supported by this analyzer. Note for developers, any additions to this list will need
    -  101   -
          * to be explicitly handled in extractFiles().
    +
          */
    +  101  8
         private static final Set<String> ZIPPABLES = newHashSet("zip", "ear", "war", "jar", "sar", "apk", "nupkg");
     102   -
          */
    -  103  1
         private static final Set<String> EXTENSIONS = newHashSet("tar", "gz", "tgz");
    +
         /**
    +  103   +
          * The set of file extensions supported by this analyzer. Note for developers, any additions to this list will need to be
     104   -
     
    +
          * explicitly handled in extractFiles().
     105   -
         /**
    -  106   -
          * The set of file extensions to remove from the engine's collection of dependencies.
    +
          */
    +  106  8
         private static final Set<String> EXTENSIONS = newHashSet("tar", "gz", "tgz");
     107   -
          */
    -  108  1
         private static final Set<String> REMOVE_FROM_ANALYSIS = newHashSet("zip", "tar", "gz", "tgz"); //TODO add nupkg, apk, sar?
    +
     
    +  108   +
         /**
     109   -
     
    +
          * Detects files with extensions to remove from the engine's collection of dependencies.
     110   +
          */
    +  111  8
         private static final FileFilter REMOVE_FROM_ANALYSIS = FileFilterBuilder.newInstance().addExtensions("zip", "tar", "gz", "tgz").build();
    +  112   +
     
    +  113  
         static {
    -  111  1
             final String additionalZipExt = Settings.getString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS);
    -  112  1
             if (additionalZipExt != null) {
    -  113  0
                 final Set<String> ext = new HashSet<String>(Arrays.asList(additionalZipExt));
    -  114  0
                 ZIPPABLES.addAll(ext);
    -  115   -
             }
    -  116  1
             EXTENSIONS.addAll(ZIPPABLES);
    -  117  1
         }
    +  114  8
             final String additionalZipExt = Settings.getString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS);
    +  115  8
             if (additionalZipExt != null) {
    +  116  0
                 final Set<String> ext = new HashSet<String>(Arrays.asList(additionalZipExt));
    +  117  0
                 ZIPPABLES.addAll(ext);
     118   -
     
    -  119   -
         /**
    +
             }
    +  119  8
             EXTENSIONS.addAll(ZIPPABLES);
     120   -
          * Returns a list of file EXTENSIONS supported by this analyzer.
    +
         }
     121   -
          *
    +
     
     122   -
          * @return a list of file EXTENSIONS supported by this analyzer.
    +
         /**
     123   -
          */
    +
          * The file filter used to filter supported files.
     124   -
         @Override
    -  125   -
         public Set<String> getSupportedExtensions() {
    -  126  850
             return EXTENSIONS;
    +
          */
    +  125  8
         private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(EXTENSIONS).build();
    +  126   +
     
     127   -
         }
    +
         @Override
     128   -
     
    -  129   -
         /**
    +
         protected FileFilter getFileFilter() {
    +  129  6824
             return FILTER;
     130   -
          * Returns the name of the analyzer.
    +
         }
     131   -
          *
    +
     
     132   -
          * @return the name of the analyzer.
    +
         /**
     133   -
          */
    +
          * Detects files with .zip extension.
     134   -
         @Override
    -  135   -
         public String getName() {
    -  136  4
             return ANALYZER_NAME;
    +
          */
    +  135  8
         private static final FileFilter ZIP_FILTER = FileFilterBuilder.newInstance().addExtensions("zip").build();
    +  136   +
     
     137   -
         }
    +
         /**
     138   -
     
    +
          * Returns the name of the analyzer.
     139   -
         /**
    +
          *
     140   -
          * Returns the phase that the analyzer is intended to run in.
    +
          * @return the name of the analyzer.
     141   -
          *
    +
          */
     142   -
          * @return the phase that the analyzer is intended to run in.
    +
         @Override
     143   -
          */
    -  144   -
         @Override
    +
         public String getName() {
    +  144  32
             return ANALYZER_NAME;
     145   -
         public AnalysisPhase getAnalysisPhase() {
    -  146  1
             return ANALYSIS_PHASE;
    +
         }
    +  146   +
     
     147   -
         }
    +
         /**
     148   -
         //</editor-fold>
    +
          * Returns the phase that the analyzer is intended to run in.
     149   -
     
    +
          *
     150   -
         /**
    +
          * @return the phase that the analyzer is intended to run in.
     151   -
          * Returns the key used in the properties file to reference the analyzer's enabled property.
    +
          */
     152   -
          *
    +
         @Override
     153   -
          * @return the analyzer's enabled property setting key
    -  154   -
          */
    +
         public AnalysisPhase getAnalysisPhase() {
    +  154  16
             return ANALYSIS_PHASE;
     155   -
         @Override
    +
         }
     156   -
         protected String getAnalyzerEnabledSettingKey() {
    -  157  2
             return Settings.KEYS.ANALYZER_ARCHIVE_ENABLED;
    +
         //</editor-fold>
    +  157   +
     
     158   -
         }
    +
         /**
     159   -
     
    +
          * Returns the key used in the properties file to reference the analyzer's enabled property.
     160   -
         /**
    +
          *
     161   -
          * The initialize method does nothing for this Analyzer.
    +
          * @return the analyzer's enabled property setting key
     162   -
          *
    +
          */
     163   -
          * @throws Exception is thrown if there is an exception deleting or creating temporary files
    +
         @Override
     164   -
          */
    -  165   -
         @Override
    +
         protected String getAnalyzerEnabledSettingKey() {
    +  165  24
             return Settings.KEYS.ANALYZER_ARCHIVE_ENABLED;
     166   -
         public void initializeFileTypeAnalyzer() throws Exception {
    -  167  1
             final File baseDir = Settings.getTempDirectory();
    -  168  1
             tempFileLocation = File.createTempFile("check", "tmp", baseDir);
    -  169  1
             if (!tempFileLocation.delete()) {
    -  170  0
                 final String msg = String.format("Unable to delete temporary file '%s'.", tempFileLocation.getAbsolutePath());
    -  171  0
                 throw new AnalysisException(msg);
    -  172   -
             }
    -  173  1
             if (!tempFileLocation.mkdirs()) {
    -  174  0
                 final String msg = String.format("Unable to create directory '%s'.", tempFileLocation.getAbsolutePath());
    -  175  0
                 throw new AnalysisException(msg);
    -  176   -
             }
    -  177  1
         }
    -  178   -
     
    -  179   -
         /**
    -  180   -
          * The close method deletes any temporary files and directories created during analysis.
    -  181   -
          *
    -  182   -
          * @throws Exception thrown if there is an exception deleting temporary files
    -  183   -
          */
    -  184   -
         @Override
    -  185   -
         public void close() throws Exception {
    -  186  1
             if (tempFileLocation != null && tempFileLocation.exists()) {
    -  187  1
                 LOGGER.log(Level.FINE, "Attempting to delete temporary files");
    -  188  1
                 final boolean success = FileUtils.delete(tempFileLocation);
    -  189  1
                 if (!success && tempFileLocation != null && tempFileLocation.exists() && tempFileLocation.list().length > 0) {
    -  190  0
                     LOGGER.log(Level.WARNING, "Failed to delete some temporary files, see the log for more details");
    -  191   -
                 }
    -  192   -
             }
    -  193  1
         }
    -  194   -
     
    -  195   -
         /**
    -  196   -
          * Analyzes a given dependency. If the dependency is an archive, such as a WAR or EAR, the contents are extracted,
    -  197   -
          * scanned, and added to the list of dependencies within the engine.
    -  198   -
          *
    -  199   -
          * @param dependency the dependency to analyze
    -  200   -
          * @param engine the engine scanning
    -  201   -
          * @throws AnalysisException thrown if there is an analysis exception
    -  202   -
          */
    -  203   -
         @Override
    -  204   -
         public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException {
    -  205  2
             final File f = new File(dependency.getActualFilePath());
    -  206  2
             final File tmpDir = getNextTempDirectory();
    -  207  2
             extractFiles(f, tmpDir, engine);
    -  208   -
     
    -  209   -
             //make a copy
    -  210  2
             List<Dependency> dependencies = new ArrayList<Dependency>(engine.getDependencies());
    -  211  2
             engine.scan(tmpDir);
    -  212  2
             List<Dependency> newDependencies = engine.getDependencies();
    -  213  2
             if (dependencies.size() != newDependencies.size()) {
    -  214   -
                 //get the new dependencies
    -  215  0
                 final Set<Dependency> dependencySet = new HashSet<Dependency>();
    -  216  0
                 dependencySet.addAll(newDependencies);
    -  217  0
                 dependencySet.removeAll(dependencies);
    -  218   -
     
    -  219  0
                 for (Dependency d : dependencySet) {
    -  220   -
                     //fix the dependency's display name and path
    -  221  0
                     final String displayPath = String.format("%s%s",
    -  222   -
                             dependency.getFilePath(),
    -  223   -
                             d.getActualFilePath().substring(tmpDir.getAbsolutePath().length()));
    -  224  0
                     final String displayName = String.format("%s: %s",
    -  225   -
                             dependency.getFileName(),
    -  226   -
                             d.getFileName());
    -  227  0
                     d.setFilePath(displayPath);
    -  228  0
                     d.setFileName(displayName);
    -  229   -
     
    -  230   -
                     //TODO - can we get more evidence from the parent? EAR contains module name, etc.
    -  231   -
                     //analyze the dependency (i.e. extract files) if it is a supported type.
    -  232  0
                     if (this.supportsExtension(d.getFileExtension()) && scanDepth < MAX_SCAN_DEPTH) {
    -  233  0
                         scanDepth += 1;
    -  234  0
                         analyze(d, engine);
    -  235  0
                         scanDepth -= 1;
    -  236   -
                     }
    -  237  0
                 }
    -  238   -
             }
    -  239  2
             if (this.REMOVE_FROM_ANALYSIS.contains(dependency.getFileExtension())) {
    -  240  0
                 if ("zip".equals(dependency.getFileExtension()) && isZipFileActuallyJarFile(dependency)) {
    -  241  0
                     final File tdir = getNextTempDirectory();
    -  242  0
                     final String fileName = dependency.getFileName();
    -  243   -
     
    -  244  0
                     LOGGER.info(String.format("The zip file '%s' appears to be a JAR file, making a copy and analyzing it as a JAR.", fileName));
    -  245   -
     
    -  246  0
                     final File tmpLoc = new File(tdir, fileName.substring(0, fileName.length() - 3) + "jar");
    -  247   -
                     try {
    -  248  0
                         org.apache.commons.io.FileUtils.copyFile(tdir, tmpLoc);
    -  249  0
                         dependencies = new ArrayList<Dependency>(engine.getDependencies());
    -  250  0
                         engine.scan(tmpLoc);
    -  251  0
                         newDependencies = engine.getDependencies();
    -  252  0
                         if (dependencies.size() != newDependencies.size()) {
    -  253   -
                             //get the new dependencies
    -  254  0
                             final Set<Dependency> dependencySet = new HashSet<Dependency>();
    -  255  0
                             dependencySet.addAll(newDependencies);
    -  256  0
                             dependencySet.removeAll(dependencies);
    -  257  0
                             if (dependencySet.size() != 1) {
    -  258  0
                                 LOGGER.info("Deep copy of ZIP to JAR file resulted in more then one dependency?");
    -  259   -
                             }
    -  260  0
                             for (Dependency d : dependencySet) {
    -  261   -
                                 //fix the dependency's display name and path
    -  262  0
                                 d.setFilePath(dependency.getFilePath());
    -  263  0
                                 d.setDisplayFileName(dependency.getFileName());
    -  264  0
                             }
    -  265   -
                         }
    -  266  0
                     } catch (IOException ex) {
    -  267  0
                         final String msg = String.format("Unable to perform deep copy on '%s'", dependency.getActualFile().getPath());
    -  268  0
                         LOGGER.log(Level.FINE, msg, ex);
    -  269  0
                     }
    -  270   -
                 }
    -  271  0
                 engine.getDependencies().remove(dependency);
    -  272   -
             }
    -  273  2
             Collections.sort(engine.getDependencies());
    -  274  2
         }
    -  275   -
     
    -  276   -
         /**
    -  277   -
          * Retrieves the next temporary directory to extract an archive too.
    -  278   -
          *
    -  279   -
          * @return a directory
    -  280   -
          * @throws AnalysisException thrown if unable to create temporary directory
    -  281   -
          */
    -  282   -
         private File getNextTempDirectory() throws AnalysisException {
    -  283  2
             dirCount += 1;
    -  284  2
             final File directory = new File(tempFileLocation, String.valueOf(dirCount));
    -  285   -
             //getting an exception for some directories not being able to be created; might be because the directory already exists?
    -  286  2
             if (directory.exists()) {
    -  287  0
                 return getNextTempDirectory();
    -  288   -
             }
    -  289  2
             if (!directory.mkdirs()) {
    -  290  0
                 final String msg = String.format("Unable to create temp directory '%s'.", directory.getAbsolutePath());
    -  291  0
                 throw new AnalysisException(msg);
    -  292   -
             }
    -  293  2
             return directory;
    -  294  
         }
    -  295   +  167  
     
    -  296   +  168  
         /**
    -  297   -
          * Extracts the contents of an archive into the specified directory.
    -  298   +  169   +
          * The initialize method does nothing for this Analyzer.
    +  170  
          *
    -  299   -
          * @param archive an archive file such as a WAR or EAR
    -  300   -
          * @param destination a directory to extract the contents to
    -  301   -
          * @param engine the scanning engine
    -  302   -
          * @throws AnalysisException thrown if the archive is not found
    -  303   +  171   +
          * @throws Exception is thrown if there is an exception deleting or creating temporary files
    +  172  
          */
    -  304   -
         private void extractFiles(File archive, File destination, Engine engine) throws AnalysisException {
    -  305  2
             if (archive == null || destination == null) {
    -  306  0
                 return;
    -  307   +  173   +
         @Override
    +  174   +
         public void initializeFileTypeAnalyzer() throws Exception {
    +  175  8
             final File baseDir = Settings.getTempDirectory();
    +  176  8
             tempFileLocation = File.createTempFile("check", "tmp", baseDir);
    +  177  8
             if (!tempFileLocation.delete()) {
    +  178  0
                 final String msg = String.format("Unable to delete temporary file '%s'.", tempFileLocation.getAbsolutePath());
    +  179  0
                 throw new AnalysisException(msg);
    +  180  
             }
    -  308   +  181  8
             if (!tempFileLocation.mkdirs()) {
    +  182  0
                 final String msg = String.format("Unable to create directory '%s'.", tempFileLocation.getAbsolutePath());
    +  183  0
                 throw new AnalysisException(msg);
    +  184   +
             }
    +  185  8
         }
    +  186  
     
    -  309  2
             FileInputStream fis = null;
    +  187   +
         /**
    +  188   +
          * The close method deletes any temporary files and directories created during analysis.
    +  189   +
          *
    +  190   +
          * @throws Exception thrown if there is an exception deleting temporary files
    +  191   +
          */
    +  192   +
         @Override
    +  193   +
         public void close() throws Exception {
    +  194  8
             if (tempFileLocation != null && tempFileLocation.exists()) {
    +  195  8
                 LOGGER.debug("Attempting to delete temporary files");
    +  196  8
                 final boolean success = FileUtils.delete(tempFileLocation);
    +  197  8
                 if (!success && tempFileLocation != null && tempFileLocation.exists() && tempFileLocation.list().length > 0) {
    +  198  0
                     LOGGER.warn("Failed to delete some temporary files, see the log for more details");
    +  199   +
                 }
    +  200   +
             }
    +  201  8
         }
    +  202   +
     
    +  203   +
         /**
    +  204   +
          * Analyzes a given dependency. If the dependency is an archive, such as a WAR or EAR, the contents are extracted, scanned,
    +  205   +
          * and added to the list of dependencies within the engine.
    +  206   +
          *
    +  207   +
          * @param dependency the dependency to analyze
    +  208   +
          * @param engine the engine scanning
    +  209   +
          * @throws AnalysisException thrown if there is an analysis exception
    +  210   +
          */
    +  211   +
         @Override
    +  212   +
         public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException {
    +  213  16
             final File f = new File(dependency.getActualFilePath());
    +  214  16
             final File tmpDir = getNextTempDirectory();
    +  215  16
             extractFiles(f, tmpDir, engine);
    +  216   +
     
    +  217   +
             //make a copy
    +  218  16
             List<Dependency> dependencies = new ArrayList<Dependency>(engine.getDependencies());
    +  219  16
             engine.scan(tmpDir);
    +  220  16
             List<Dependency> newDependencies = engine.getDependencies();
    +  221  16
             if (dependencies.size() != newDependencies.size()) {
    +  222   +
                 //get the new dependencies
    +  223  0
                 final Set<Dependency> dependencySet = new HashSet<Dependency>();
    +  224  0
                 dependencySet.addAll(newDependencies);
    +  225  0
                 dependencySet.removeAll(dependencies);
    +  226   +
     
    +  227  0
                 for (Dependency d : dependencySet) {
    +  228   +
                     //fix the dependency's display name and path
    +  229  0
                     final String displayPath = String.format("%s%s",
    +  230   +
                             dependency.getFilePath(),
    +  231   +
                             d.getActualFilePath().substring(tmpDir.getAbsolutePath().length()));
    +  232  0
                     final String displayName = String.format("%s: %s",
    +  233   +
                             dependency.getFileName(),
    +  234   +
                             d.getFileName());
    +  235  0
                     d.setFilePath(displayPath);
    +  236  0
                     d.setFileName(displayName);
    +  237   +
     
    +  238   +
                     //TODO - can we get more evidence from the parent? EAR contains module name, etc.
    +  239   +
                     //analyze the dependency (i.e. extract files) if it is a supported type.
    +  240  0
                     if (this.accept(d.getActualFile()) && scanDepth < MAX_SCAN_DEPTH) {
    +  241  0
                         scanDepth += 1;
    +  242  0
                         analyze(d, engine);
    +  243  0
                         scanDepth -= 1;
    +  244   +
                     }
    +  245  0
                 }
    +  246   +
             }
    +  247  16
             if (REMOVE_FROM_ANALYSIS.accept(dependency.getActualFile())) {
    +  248  0
                 if (ZIP_FILTER.accept(dependency.getActualFile()) && isZipFileActuallyJarFile(dependency)) {
    +  249  0
                     final File tdir = getNextTempDirectory();
    +  250  0
                     final String fileName = dependency.getFileName();
    +  251   +
     
    +  252  0
                     LOGGER.info(String.format("The zip file '%s' appears to be a JAR file, making a copy and analyzing it as a JAR.", fileName));
    +  253   +
     
    +  254  0
                     final File tmpLoc = new File(tdir, fileName.substring(0, fileName.length() - 3) + "jar");
    +  255   +
                     try {
    +  256  0
                         org.apache.commons.io.FileUtils.copyFile(tdir, tmpLoc);
    +  257  0
                         dependencies = new ArrayList<Dependency>(engine.getDependencies());
    +  258  0
                         engine.scan(tmpLoc);
    +  259  0
                         newDependencies = engine.getDependencies();
    +  260  0
                         if (dependencies.size() != newDependencies.size()) {
    +  261   +
                             //get the new dependencies
    +  262  0
                             final Set<Dependency> dependencySet = new HashSet<Dependency>();
    +  263  0
                             dependencySet.addAll(newDependencies);
    +  264  0
                             dependencySet.removeAll(dependencies);
    +  265  0
                             if (dependencySet.size() != 1) {
    +  266  0
                                 LOGGER.info("Deep copy of ZIP to JAR file resulted in more then one dependency?");
    +  267   +
                             }
    +  268  0
                             for (Dependency d : dependencySet) {
    +  269   +
                                 //fix the dependency's display name and path
    +  270  0
                                 d.setFilePath(dependency.getFilePath());
    +  271  0
                                 d.setDisplayFileName(dependency.getFileName());
    +  272  0
                             }
    +  273   +
                         }
    +  274  0
                     } catch (IOException ex) {
    +  275  0
                         LOGGER.debug("Unable to perform deep copy on '{}'", dependency.getActualFile().getPath(), ex);
    +  276  0
                     }
    +  277   +
                 }
    +  278  0
                 engine.getDependencies().remove(dependency);
    +  279   +
             }
    +  280  16
             Collections.sort(engine.getDependencies());
    +  281  16
         }
    +  282   +
     
    +  283   +
         /**
    +  284   +
          * Retrieves the next temporary directory to extract an archive too.
    +  285   +
          *
    +  286   +
          * @return a directory
    +  287   +
          * @throws AnalysisException thrown if unable to create temporary directory
    +  288   +
          */
    +  289   +
         private File getNextTempDirectory() throws AnalysisException {
    +  290  16
             dirCount += 1;
    +  291  16
             final File directory = new File(tempFileLocation, String.valueOf(dirCount));
    +  292   +
             //getting an exception for some directories not being able to be created; might be because the directory already exists?
    +  293  16
             if (directory.exists()) {
    +  294  0
                 return getNextTempDirectory();
    +  295   +
             }
    +  296  16
             if (!directory.mkdirs()) {
    +  297  0
                 final String msg = String.format("Unable to create temp directory '%s'.", directory.getAbsolutePath());
    +  298  0
                 throw new AnalysisException(msg);
    +  299   +
             }
    +  300  16
             return directory;
    +  301   +
         }
    +  302   +
     
    +  303   +
         /**
    +  304   +
          * Extracts the contents of an archive into the specified directory.
    +  305   +
          *
    +  306   +
          * @param archive an archive file such as a WAR or EAR
    +  307   +
          * @param destination a directory to extract the contents to
    +  308   +
          * @param engine the scanning engine
    +  309   +
          * @throws AnalysisException thrown if the archive is not found
     310   -
             try {
    -  311  2
                 fis = new FileInputStream(archive);
    -  312  0
             } catch (FileNotFoundException ex) {
    -  313  0
                 LOGGER.log(Level.FINE, null, ex);
    -  314  0
                 throw new AnalysisException("Archive file was not found.", ex);
    -  315  2
             }
    -  316  2
             final String archiveExt = FileUtils.getFileExtension(archive.getName()).toLowerCase();
    +
          */
    +  311   +
         private void extractFiles(File archive, File destination, Engine engine) throws AnalysisException {
    +  312  16
             if (archive == null || destination == null) {
    +  313  0
                 return;
    +  314   +
             }
    +  315   +
     
    +  316  16
             FileInputStream fis = null;
     317  
             try {
    -  318  2
                 if (ZIPPABLES.contains(archiveExt)) {
    -  319  2
                     extractArchive(new ZipArchiveInputStream(new BufferedInputStream(fis)), destination, engine);
    -  320  0
                 } else if ("tar".equals(archiveExt)) {
    -  321  0
                     extractArchive(new TarArchiveInputStream(new BufferedInputStream(fis)), destination, engine);
    -  322  0
                 } else if ("gz".equals(archiveExt) || "tgz".equals(archiveExt)) {
    -  323  0
                     final String uncompressedName = GzipUtils.getUncompressedFilename(archive.getName());
    -  324  0
                     final String uncompressedExt = FileUtils.getFileExtension(uncompressedName).toLowerCase();
    -  325  0
                     if (engine.supportsExtension(uncompressedExt)) {
    -  326  0
                         decompressFile(new GzipCompressorInputStream(new BufferedInputStream(fis)), new File(destination, uncompressedName));
    -  327   +  318  16
                 fis = new FileInputStream(archive);
    +  319  0
             } catch (FileNotFoundException ex) {
    +  320  0
                 LOGGER.debug("", ex);
    +  321  0
                 throw new AnalysisException("Archive file was not found.", ex);
    +  322  16
             }
    +  323  16
             final String archiveExt = FileUtils.getFileExtension(archive.getName()).toLowerCase();
    +  324   +
             try {
    +  325  16
                 if (ZIPPABLES.contains(archiveExt)) {
    +  326  16
                     extractArchive(new ZipArchiveInputStream(new BufferedInputStream(fis)), destination, engine);
    +  327  0
                 } else if ("tar".equals(archiveExt)) {
    +  328  0
                     extractArchive(new TarArchiveInputStream(new BufferedInputStream(fis)), destination, engine);
    +  329  0
                 } else if ("gz".equals(archiveExt) || "tgz".equals(archiveExt)) {
    +  330  0
                     final String uncompressedName = GzipUtils.getUncompressedFilename(archive.getName());
    +  331  0
                     final File f = new File(destination, uncompressedName);
    +  332  0
                     if (engine.accept(f)) {
    +  333  0
                         decompressFile(new GzipCompressorInputStream(new BufferedInputStream(fis)), f);
    +  334  
                     }
    -  328   +  335  
                 }
    -  329  0
             } catch (ArchiveExtractionException ex) {
    -  330  0
                 final String msg = String.format("Exception extracting archive '%s'.", archive.getName());
    -  331  0
                 LOGGER.log(Level.WARNING, msg);
    -  332  0
                 LOGGER.log(Level.FINE, null, ex);
    -  333  0
             } catch (IOException ex) {
    -  334  0
                 final String msg = String.format("Exception reading archive '%s'.", archive.getName());
    -  335  0
                 LOGGER.log(Level.WARNING, msg);
    -  336  0
                 LOGGER.log(Level.FINE, null, ex);
    -  337   +  336  0
             } catch (ArchiveExtractionException ex) {
    +  337  0
                 LOGGER.warn("Exception extracting archive '{}'.", archive.getName());
    +  338  0
                 LOGGER.debug("", ex);
    +  339  0
             } catch (IOException ex) {
    +  340  0
                 LOGGER.warn("Exception reading archive '{}'.", archive.getName());
    +  341  0
                 LOGGER.debug("", ex);
    +  342  
             } finally {
    -  338  0
                 try {
    -  339  2
                     fis.close();
    -  340  0
                 } catch (IOException ex) {
    -  341  0
                     LOGGER.log(Level.FINE, null, ex);
    -  342  2
                 }
    -  343  0
             }
    -  344  2
         }
    -  345   -
     
    -  346   -
         /**
    -  347   -
          * Extracts files from an archive.
    -  348   -
          *
    -  349   -
          * @param input the archive to extract files from
    +  343  0
                 try {
    +  344  16
                     fis.close();
    +  345  0
                 } catch (IOException ex) {
    +  346  0
                     LOGGER.debug("", ex);
    +  347  16
                 }
    +  348  0
             }
    +  349  16
         }
     350   -
          * @param destination the location to write the files too
    +
     
     351   -
          * @param engine the dependency-check engine
    +
         /**
     352   -
          * @throws ArchiveExtractionException thrown if there is an exception extracting files from the archive
    +
          * Extracts files from an archive.
     353   -
          */
    +
          *
     354   -
         private void extractArchive(ArchiveInputStream input, File destination, Engine engine) throws ArchiveExtractionException {
    +
          * @param input the archive to extract files from
     355   -
             ArchiveEntry entry;
    +
          * @param destination the location to write the files too
     356   +
          * @param engine the dependency-check engine
    +  357   +
          * @throws ArchiveExtractionException thrown if there is an exception extracting files from the archive
    +  358   +
          */
    +  359   +
         private void extractArchive(ArchiveInputStream input, File destination, Engine engine) throws ArchiveExtractionException {
    +  360   +
             ArchiveEntry entry;
    +  361  
             try {
    -  357  887
                 while ((entry = input.getNextEntry()) != null) {
    -  358  885
                     if (entry.isDirectory()) {
    -  359  36
                         final File d = new File(destination, entry.getName());
    -  360  36
                         if (!d.exists()) {
    -  361  36
                             if (!d.mkdirs()) {
    -  362  0
                                 final String msg = String.format("Unable to create directory '%s'.", d.getAbsolutePath());
    -  363  0
                                 throw new AnalysisException(msg);
    -  364   +  362  7096
                 while ((entry = input.getNextEntry()) != null) {
    +  363  7080
                     if (entry.isDirectory()) {
    +  364  288
                         final File d = new File(destination, entry.getName());
    +  365  288
                         if (!d.exists()) {
    +  366  288
                             if (!d.mkdirs()) {
    +  367  0
                                 final String msg = String.format("Unable to create directory '%s'.", d.getAbsolutePath());
    +  368  0
                                 throw new AnalysisException(msg);
    +  369  
                             }
    -  365   +  370  
                         }
    -  366  36
                     } else {
    -  367  849
                         final File file = new File(destination, entry.getName());
    -  368  849
                         final String ext = FileUtils.getFileExtension(file.getName());
    -  369  849
                         if (engine.supportsExtension(ext)) {
    -  370  0
                             final String extracting = String.format("Extracting '%s'", file.getPath());
    -  371  0
                             LOGGER.fine(extracting);
    -  372  0
                             BufferedOutputStream bos = null;
    -  373  0
                             FileOutputStream fos = null;
    -  374   +  371  288
                     } else {
    +  372  6792
                         final File file = new File(destination, entry.getName());
    +  373  6792
                         if (engine.accept(file)) {
    +  374  0
                             LOGGER.debug("Extracting '{}'", file.getPath());
    +  375  0
                             BufferedOutputStream bos = null;
    +  376  0
                             FileOutputStream fos = null;
    +  377  
                             try {
    -  375  0
                                 final File parent = file.getParentFile();
    -  376  0
                                 if (!parent.isDirectory()) {
    -  377  0
                                     if (!parent.mkdirs()) {
    -  378  0
                                         final String msg = String.format("Unable to build directory '%s'.", parent.getAbsolutePath());
    -  379  0
                                         throw new AnalysisException(msg);
    -  380   +  378  0
                                 final File parent = file.getParentFile();
    +  379  0
                                 if (!parent.isDirectory()) {
    +  380  0
                                     if (!parent.mkdirs()) {
    +  381  0
                                         final String msg = String.format("Unable to build directory '%s'.", parent.getAbsolutePath());
    +  382  0
                                         throw new AnalysisException(msg);
    +  383  
                                     }
    -  381   -
                                 }
    -  382  0
                                 fos = new FileOutputStream(file);
    -  383  0
                                 bos = new BufferedOutputStream(fos, BUFFER_SIZE);
     384   +
                                 }
    +  385  0
                                 fos = new FileOutputStream(file);
    +  386  0
                                 bos = new BufferedOutputStream(fos, BUFFER_SIZE);
    +  387  
                                 int count;
    -  385  0
                                 final byte[] data = new byte[BUFFER_SIZE];
    -  386  0
                                 while ((count = input.read(data, 0, BUFFER_SIZE)) != -1) {
    -  387  0
                                     bos.write(data, 0, count);
    -  388   +  388  0
                                 final byte[] data = new byte[BUFFER_SIZE];
    +  389  0
                                 while ((count = input.read(data, 0, BUFFER_SIZE)) != -1) {
    +  390  0
                                     bos.write(data, 0, count);
    +  391  
                                 }
    -  389  0
                                 bos.flush();
    -  390  0
                             } catch (FileNotFoundException ex) {
    -  391  0
                                 LOGGER.log(Level.FINE, null, ex);
    -  392  0
                                 final String msg = String.format("Unable to find file '%s'.", file.getName());
    -  393  0
                                 throw new AnalysisException(msg, ex);
    -  394  0
                             } catch (IOException ex) {
    -  395  0
                                 LOGGER.log(Level.FINE, null, ex);
    -  396  0
                                 final String msg = String.format("IO Exception while parsing file '%s'.", file.getName());
    -  397  0
                                 throw new AnalysisException(msg, ex);
    -  398   +  392  0
                                 bos.flush();
    +  393  0
                             } catch (FileNotFoundException ex) {
    +  394  0
                                 LOGGER.debug("", ex);
    +  395  0
                                 final String msg = String.format("Unable to find file '%s'.", file.getName());
    +  396  0
                                 throw new AnalysisException(msg, ex);
    +  397  0
                             } catch (IOException ex) {
    +  398  0
                                 LOGGER.debug("", ex);
    +  399  0
                                 final String msg = String.format("IO Exception while parsing file '%s'.", file.getName());
    +  400  0
                                 throw new AnalysisException(msg, ex);
    +  401  
                             } finally {
    -  399  0
                                 if (bos != null) {
    -  400   +  402  0
                                 if (bos != null) {
    +  403  
                                     try {
    -  401  0
                                         bos.close();
    -  402  0
                                     } catch (IOException ex) {
    -  403  0
                                         LOGGER.log(Level.FINEST, null, ex);
    -  404  0
                                     }
    -  405   +  404  0
                                         bos.close();
    +  405  0
                                     } catch (IOException ex) {
    +  406  0
                                         LOGGER.trace("", ex);
    +  407  0
                                     }
    +  408  
                                 }
    -  406  0
                                 if (fos != null) {
    -  407   +  409  0
                                 if (fos != null) {
    +  410  
                                     try {
    -  408  0
                                         fos.close();
    -  409  0
                                     } catch (IOException ex) {
    -  410  0
                                         LOGGER.log(Level.FINEST, null, ex);
    -  411  0
                                     }
    -  412   +  411  0
                                         fos.close();
    +  412  0
                                     } catch (IOException ex) {
    +  413  0
                                         LOGGER.trace("", ex);
    +  414  0
                                     }
    +  415  
                                 }
    -  413   -
                             }
    -  414   -
                         }
    -  415  849
                     }
     416   -
                 }
    -  417  0
             } catch (IOException ex) {
    -  418  0
                 throw new ArchiveExtractionException(ex);
    -  419  0
             } catch (Throwable ex) {
    -  420  0
                 throw new ArchiveExtractionException(ex);
    -  421   -
             } finally {
    -  422  2
                 if (input != null) {
    -  423   -
                     try {
    -  424  2
                         input.close();
    -  425  0
                     } catch (IOException ex) {
    -  426  0
                         LOGGER.log(Level.FINEST, null, ex);
    -  427  2
                     }
    -  428   -
                 }
    -  429   -
             }
    -  430  2
         }
    -  431   -
     
    -  432   -
         /**
    -  433   -
          * Decompresses a file.
    -  434   -
          *
    -  435   -
          * @param inputStream the compressed file
    -  436   -
          * @param outputFile the location to write the decompressed file
    -  437   -
          * @throws ArchiveExtractionException thrown if there is an exception decompressing the file
    -  438   -
          */
    -  439   -
         private void decompressFile(CompressorInputStream inputStream, File outputFile) throws ArchiveExtractionException {
    -  440  0
             final String msg = String.format("Decompressing '%s'", outputFile.getPath());
    -  441  0
             LOGGER.fine(msg);
    -  442  0
             FileOutputStream out = null;
    -  443   -
             try {
    -  444  0
                 out = new FileOutputStream(outputFile);
    -  445  0
                 final byte[] buffer = new byte[BUFFER_SIZE];
    -  446  0
                 int n = 0;
    -  447  0
                 while (-1 != (n = inputStream.read(buffer))) {
    -  448  0
                     out.write(buffer, 0, n);
    -  449   -
                 }
    -  450  0
             } catch (FileNotFoundException ex) {
    -  451  0
                 LOGGER.log(Level.FINE, null, ex);
    -  452  0
                 throw new ArchiveExtractionException(ex);
    -  453  0
             } catch (IOException ex) {
    -  454  0
                 LOGGER.log(Level.FINE, null, ex);
    -  455  0
                 throw new ArchiveExtractionException(ex);
    -  456   -
             } finally {
    -  457  0
                 if (out != null) {
    -  458   -
                     try {
    -  459  0
                         out.close();
    -  460  0
                     } catch (IOException ex) {
    -  461  0
                         LOGGER.log(Level.FINEST, null, ex);
    -  462  0
                     }
    -  463   -
                 }
    -  464   -
             }
    -  465  0
         }
    -  466   -
     
    -  467   -
         /**
    -  468   -
          * Attempts to determine if a zip file is actually a JAR file.
    -  469   -
          *
    -  470   -
          * @param dependency the dependency to check
    -  471   -
          * @return true if the dependency appears to be a JAR file; otherwise false
    -  472   -
          */
    -  473   -
         private boolean isZipFileActuallyJarFile(Dependency dependency) {
    -  474  0
             boolean isJar = false;
    -  475  0
             ZipFile zip = null;
    -  476   -
             try {
    -  477  0
                 zip = new ZipFile(dependency.getActualFilePath());
    -  478  0
                 if (zip.getEntry("META-INF/MANIFEST.MF") != null
    -  479   -
                         || zip.getEntry("META-INF/maven") != null) {
    -  480  0
                     final Enumeration<ZipArchiveEntry> entries = zip.getEntries();
    -  481  0
                     while (entries.hasMoreElements()) {
    -  482  0
                         final ZipArchiveEntry entry = entries.nextElement();
    -  483  0
                         if (!entry.isDirectory()) {
    -  484  0
                             final String name = entry.getName().toLowerCase();
    -  485  0
                             if (name.endsWith(".class")) {
    -  486  0
                                 isJar = true;
    -  487  0
                                 break;
    -  488  
                             }
    -  489   +  417  
                         }
    -  490  0
                     }
    -  491   +  418  6792
                     }
    +  419  
                 }
    -  492  0
             } catch (IOException ex) {
    -  493  0
                 LOGGER.log(Level.FINE, String.format("Unable to unzip zip file '%s'", dependency.getFilePath()), ex);
    -  494   +  420  0
             } catch (IOException ex) {
    +  421  0
                 throw new ArchiveExtractionException(ex);
    +  422  0
             } catch (Throwable ex) {
    +  423  0
                 throw new ArchiveExtractionException(ex);
    +  424  
             } finally {
    -  495  0
                 ZipFile.closeQuietly(zip);
    -  496  0
             }
    -  497   +  425  16
                 if (input != null) {
    +  426   +
                     try {
    +  427  16
                         input.close();
    +  428  0
                     } catch (IOException ex) {
    +  429  0
                         LOGGER.trace("", ex);
    +  430  16
                     }
    +  431   +
                 }
    +  432   +
             }
    +  433  16
         }
    +  434  
     
    -  498  0
             return isJar;
    +  435   +
         /**
    +  436   +
          * Decompresses a file.
    +  437   +
          *
    +  438   +
          * @param inputStream the compressed file
    +  439   +
          * @param outputFile the location to write the decompressed file
    +  440   +
          * @throws ArchiveExtractionException thrown if there is an exception decompressing the file
    +  441   +
          */
    +  442   +
         private void decompressFile(CompressorInputStream inputStream, File outputFile) throws ArchiveExtractionException {
    +  443  0
             LOGGER.debug("Decompressing '{}'", outputFile.getPath());
    +  444  0
             FileOutputStream out = null;
    +  445   +
             try {
    +  446  0
                 out = new FileOutputStream(outputFile);
    +  447  0
                 final byte[] buffer = new byte[BUFFER_SIZE];
    +  448  0
                 int n = 0;
    +  449  0
                 while (-1 != (n = inputStream.read(buffer))) {
    +  450  0
                     out.write(buffer, 0, n);
    +  451   +
                 }
    +  452  0
             } catch (FileNotFoundException ex) {
    +  453  0
                 LOGGER.debug("", ex);
    +  454  0
                 throw new ArchiveExtractionException(ex);
    +  455  0
             } catch (IOException ex) {
    +  456  0
                 LOGGER.debug("", ex);
    +  457  0
                 throw new ArchiveExtractionException(ex);
    +  458   +
             } finally {
    +  459  0
                 if (out != null) {
    +  460   +
                     try {
    +  461  0
                         out.close();
    +  462  0
                     } catch (IOException ex) {
    +  463  0
                         LOGGER.trace("", ex);
    +  464  0
                     }
    +  465   +
                 }
    +  466   +
             }
    +  467  0
         }
    +  468   +
     
    +  469   +
         /**
    +  470   +
          * Attempts to determine if a zip file is actually a JAR file.
    +  471   +
          *
    +  472   +
          * @param dependency the dependency to check
    +  473   +
          * @return true if the dependency appears to be a JAR file; otherwise false
    +  474   +
          */
    +  475   +
         private boolean isZipFileActuallyJarFile(Dependency dependency) {
    +  476  0
             boolean isJar = false;
    +  477  0
             ZipFile zip = null;
    +  478   +
             try {
    +  479  0
                 zip = new ZipFile(dependency.getActualFilePath());
    +  480  0
                 if (zip.getEntry("META-INF/MANIFEST.MF") != null
    +  481   +
                         || zip.getEntry("META-INF/maven") != null) {
    +  482  0
                     final Enumeration<ZipArchiveEntry> entries = zip.getEntries();
    +  483  0
                     while (entries.hasMoreElements()) {
    +  484  0
                         final ZipArchiveEntry entry = entries.nextElement();
    +  485  0
                         if (!entry.isDirectory()) {
    +  486  0
                             final String name = entry.getName().toLowerCase();
    +  487  0
                             if (name.endsWith(".class")) {
    +  488  0
                                 isJar = true;
    +  489  0
                                 break;
    +  490   +
                             }
    +  491   +
                         }
    +  492  0
                     }
    +  493   +
                 }
    +  494  0
             } catch (IOException ex) {
    +  495  0
                 LOGGER.debug("Unable to unzip zip file '{}'", dependency.getFilePath(), ex);
    +  496   +
             } finally {
    +  497  0
                 ZipFile.closeQuietly(zip);
    +  498  0
             }
     499   +
     
    +  500  0
             return isJar;
    +  501  
         }
    -  500   +  502  
     }
    - + 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 069498409..6652ed1f5 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AssemblyAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AssemblyAnalyzer.html @@ -12,7 +12,7 @@
     
    - +
    Classes in this File Line Coverage Branch Coverage Complexity
    AssemblyAnalyzer
    67%
    84/125
    50%
    25/50
    6.875
    AssemblyAnalyzer
    67%
    86/127
    50%
    25/50
    6.875
     
    @@ -56,494 +56,526 @@  19  
     
     20   -
     import java.io.BufferedReader;
    +
     import ch.qos.cal10n.IMessageConveyor;
     21   -
     import java.io.File;
    +
     import ch.qos.cal10n.MessageConveyor;
     22   -
     import java.io.FileOutputStream;
    +
     import java.io.BufferedReader;
     23   -
     import java.io.IOException;
    +
     import java.io.File;
     24   -
     import java.io.InputStream;
    +
     import java.io.FileFilter;
     25   -
     import java.io.InputStreamReader;
    +
     import java.io.FileOutputStream;
     26   -
     import java.util.ArrayList;
    +
     import java.io.IOException;
     27   -
     import java.util.List;
    +
     import java.io.InputStream;
     28   -
     import java.util.Set;
    +
     import java.io.InputStreamReader;
     29   -
     import java.util.logging.Level;
    -  30   -
     import java.util.logging.Logger;
    -  31   -
     import javax.xml.parsers.DocumentBuilder;
    -  32   -
     import javax.xml.parsers.DocumentBuilderFactory;
    -  33   -
     import javax.xml.xpath.XPath;
    -  34   -
     import javax.xml.xpath.XPathExpressionException;
    -  35   -
     import javax.xml.xpath.XPathFactory;
    -  36  
     import org.owasp.dependencycheck.Engine;
    -  37   +  30  
     import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
    -  38   +  31  
     import org.owasp.dependencycheck.dependency.Confidence;
    -  39   +  32  
     import org.owasp.dependencycheck.dependency.Dependency;
    -  40   +  33  
     import org.owasp.dependencycheck.dependency.Evidence;
    -  41   +  34   +
     import org.owasp.dependencycheck.utils.FileFilterBuilder;
    +  35  
     import org.owasp.dependencycheck.utils.Settings;
    -  42   +  36   +
     import org.slf4j.Logger;
    +  37   +
     import org.slf4j.LoggerFactory;
    +  38  
     import org.w3c.dom.Document;
    -  43   +  39  
     import org.xml.sax.SAXException;
    +  40   +
     
    +  41   +
     import javax.xml.parsers.DocumentBuilder;
    +  42   +
     import javax.xml.parsers.DocumentBuilderFactory;
    +  43   +
     import javax.xml.xpath.XPath;
     44   -
     
    +
     import javax.xml.xpath.XPathExpressionException;
     45   -
     /**
    +
     import javax.xml.xpath.XPathFactory;
     46   -
      * Analyzer for getting company, product, and version information from a .NET assembly.
    +
     import java.util.ArrayList;
     47   -
      *
    +
     import java.util.List;
     48   -
      * @author colezlaw
    +
     import java.util.Locale;
     49   -
      *
    +
     
     50   -
      */
    -  51  7
     public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer {
    +
     /**
    +  51   +
      * Analyzer for getting company, product, and version information from a .NET assembly.
     52   -
     
    +
      *
     53   -
         /**
    +
      * @author colezlaw
     54   -
          * The analyzer name
    +
      *
     55   -
          */
    -  56   -
         private static final String ANALYZER_NAME = "Assembly Analyzer";
    +
      */
    +  56  64
     public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer {
     57   -
         /**
    -  58   -
          * The analysis phase
    -  59   -
          */
    -  60  1
         private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
    -  61   -
         /**
    -  62   -
          * The list of supported extensions
    -  63   -
          */
    -  64  1
         private static final Set<String> SUPPORTED_EXTENSIONS = newHashSet("dll", "exe");
    -  65   -
         /**
    -  66   -
          * The temp value for GrokAssembly.exe
    -  67   -
          */
    -  68  7
         private File grokAssemblyExe = null;
    -  69   -
         /**
    -  70   -
          * The DocumentBuilder for parsing the XML
    -  71   -
          */
    -  72   -
         private DocumentBuilder builder;
    -  73   -
         /**
    -  74   -
          * Logger
    -  75   -
          */
    -  76  1
         private static final Logger LOGGER = Logger.getLogger(AssemblyAnalyzer.class.getName(), "dependencycheck-resources");
    -  77  
     
    +  58   +
         /**
    +  59   +
          * The analyzer name
    +  60   +
          */
    +  61   +
         private static final String ANALYZER_NAME = "Assembly Analyzer";
    +  62   +
         /**
    +  63   +
          * The analysis phase
    +  64   +
          */
    +  65  8
         private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
    +  66   +
         /**
    +  67   +
          * The list of supported extensions
    +  68   +
          */
    +  69  8
         private static final String[] SUPPORTED_EXTENSIONS = {"dll", "exe"};
    +  70   +
         /**
    +  71   +
          * The temp value for GrokAssembly.exe
    +  72   +
          */
    +  73  64
         private File grokAssemblyExe = null;
    +  74   +
         /**
    +  75   +
          * The DocumentBuilder for parsing the XML
    +  76   +
          */
    +  77   +
         private DocumentBuilder builder;
     78  
         /**
     79   -
          * Builds the beginnings of a List for ProcessBuilder
    +
          * Message Conveyer
     80   -
          *
    -  81   -
          * @return the list of arguments to begin populating the ProcessBuilder
    +
          */
    +  81  8
         private static final IMessageConveyor MESSAGE_CONVERYOR = new MessageConveyor(Locale.getDefault());
     82   -
          */
    +
         /**
     83   -
         private List<String> buildArgumentList() {
    +
          * Logger
     84   -
             // Use file.separator as a wild guess as to whether this is Windows
    -  85  8
             final List<String> args = new ArrayList<String>();
    -  86  8
             if (!"\\".equals(System.getProperty("file.separator"))) {
    -  87  0
                 if (Settings.getString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH) != null) {
    -  88  0
                     args.add(Settings.getString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH));
    +
          */
    +  85  8
         private static final Logger LOGGER = LoggerFactory.getLogger(AssemblyAnalyzer.class);
    +  86   +
     
    +  87   +
         /**
    +  88   +
          * Builds the beginnings of a List for ProcessBuilder
     89   -
                 } else {
    -  90  0
                     args.add("mono");
    +
          *
    +  90   +
          * @return the list of arguments to begin populating the ProcessBuilder
     91   -
                 }
    +
          */
     92   -
             }
    -  93  8
             args.add(grokAssemblyExe.getPath());
    -  94   -
     
    -  95  8
             return args;
    -  96   -
         }
    -  97   -
     
    +
         private List<String> buildArgumentList() {
    +  93   +
             // Use file.separator as a wild guess as to whether this is Windows
    +  94  64
             final List<String> args = new ArrayList<String>();
    +  95  64
             if (!"\\".equals(System.getProperty("file.separator"))) {
    +  96  0
                 if (Settings.getString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH) != null) {
    +  97  0
                     args.add(Settings.getString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH));
     98   -
         /**
    -  99   -
          * Performs the analysis on a single Dependency.
    -  100   -
          *
    -  101   -
          * @param dependency the dependency to analyze
    -  102   -
          * @param engine the engine to perform the analysis under
    -  103   -
          * @throws AnalysisException if anything goes sideways
    -  104   -
          */
    -  105   -
         @Override
    -  106   -
         public void analyzeFileType(Dependency dependency, Engine engine)
    -  107   -
                 throws AnalysisException {
    -  108  3
             if (grokAssemblyExe == null) {
    -  109  0
                 LOGGER.warning("analyzer.AssemblyAnalyzer.notdeployed");
    -  110  0
                 return;
    -  111   -
             }
    -  112   -
     
    -  113  3
             final List<String> args = buildArgumentList();
    -  114  3
             args.add(dependency.getActualFilePath());
    -  115  3
             final ProcessBuilder pb = new ProcessBuilder(args);
    -  116  3
             BufferedReader rdr = null;
    -  117  3
             Document doc = null;
    -  118   -
             try {
    -  119  3
                 final Process proc = pb.start();
    -  120   -
                 // Try evacuating the error stream
    -  121  3
                 rdr = new BufferedReader(new InputStreamReader(proc.getErrorStream(), "UTF-8"));
    -  122  3
                 String line = null;
    -  123   -
                 // CHECKSTYLE:OFF
    -  124  3
                 while (rdr.ready() && (line = rdr.readLine()) != null) {
    -  125  0
                     LOGGER.log(Level.WARNING, "analyzer.AssemblyAnalyzer.grokassembly.stderr", line);
    -  126   -
                 }
    -  127   -
                 // CHECKSTYLE:ON
    -  128  3
                 int rc = 0;
    -  129  3
                 doc = builder.parse(proc.getInputStream());
    -  130   -
     
    -  131   -
                 try {
    -  132  3
                     rc = proc.waitFor();
    -  133  0
                 } catch (InterruptedException ie) {
    -  134   -
                     return;
    -  135  3
                 }
    -  136  3
                 if (rc == 3) {
    -  137  0
                     LOGGER.log(Level.FINE, "analyzer.AssemblyAnalyzer.notassembly", dependency.getActualFilePath());
    -  138   -
                     return;
    -  139  3
                 } else if (rc != 0) {
    -  140  1
                     LOGGER.log(Level.WARNING, "analyzer.AssemblyAnalyzer.grokassembly.rc", rc);
    -  141   -
                 }
    -  142   -
     
    -  143  3
                 final XPath xpath = XPathFactory.newInstance().newXPath();
    -  144   -
     
    -  145   -
                 // First, see if there was an error
    -  146  3
                 final String error = xpath.evaluate("/assembly/error", doc);
    -  147  3
                 if (error != null && !"".equals(error)) {
    -  148  1
                     throw new AnalysisException(error);
    -  149   -
                 }
    -  150   -
     
    -  151  2
                 final String version = xpath.evaluate("/assembly/version", doc);
    -  152  2
                 if (version != null) {
    -  153  2
                     dependency.getVersionEvidence().addEvidence(new Evidence("grokassembly", "version",
    -  154   -
                             version, Confidence.HIGHEST));
    -  155   -
                 }
    -  156   -
     
    -  157  2
                 final String vendor = xpath.evaluate("/assembly/company", doc);
    -  158  2
                 if (vendor != null) {
    -  159  2
                     dependency.getVendorEvidence().addEvidence(new Evidence("grokassembly", "vendor",
    -  160   -
                             vendor, Confidence.HIGH));
    -  161   -
                 }
    -  162   -
     
    -  163  2
                 final String product = xpath.evaluate("/assembly/product", doc);
    -  164  2
                 if (product != null) {
    -  165  2
                     dependency.getProductEvidence().addEvidence(new Evidence("grokassembly", "product",
    -  166   -
                             product, Confidence.HIGH));
    -  167   -
                 }
    -  168   -
     
    -  169  0
             } catch (IOException ioe) {
    -  170  0
                 throw new AnalysisException(ioe);
    -  171  0
             } catch (SAXException saxe) {
    -  172  0
                 throw new AnalysisException("Couldn't parse GrokAssembly result", saxe);
    -  173  0
             } catch (XPathExpressionException xpe) {
    -  174   -
                 // This shouldn't happen
    -  175  0
                 throw new AnalysisException(xpe);
    -  176   -
             } finally {
    -  177  3
                 if (rdr != null) {
    -  178   -
                     try {
    -  179  3
                         rdr.close();
    -  180  0
                     } catch (IOException ex) {
    -  181  0
                         LOGGER.log(Level.FINEST, "ignore", ex);
    -  182  4
                     }
    -  183   -
                 }
    -  184   -
             }
    -  185  2
         }
    -  186   -
     
    -  187   -
         /**
    -  188   -
          * Initialize the analyzer. In this case, extract GrokAssembly.exe to a temporary location.
    -  189   -
          *
    -  190   -
          * @throws Exception if anything goes wrong
    -  191   -
          */
    -  192   -
         @Override
    -  193   -
         public void initializeFileTypeAnalyzer() throws Exception {
    -  194  5
             final File tempFile = File.createTempFile("GKA", ".exe", Settings.getTempDirectory());
    -  195  5
             FileOutputStream fos = null;
    -  196  5
             InputStream is = null;
    -  197   -
             try {
    -  198  5
                 fos = new FileOutputStream(tempFile);
    -  199  5
                 is = AssemblyAnalyzer.class.getClassLoader().getResourceAsStream("GrokAssembly.exe");
    -  200  5
                 final byte[] buff = new byte[4096];
    -  201  5
                 int bread = -1;
    -  202  15
                 while ((bread = is.read(buff)) >= 0) {
    -  203  10
                     fos.write(buff, 0, bread);
    -  204   -
                 }
    -  205  5
                 grokAssemblyExe = tempFile;
    -  206   -
                 // Set the temp file to get deleted when we're done
    -  207  5
                 grokAssemblyExe.deleteOnExit();
    -  208  5
                 LOGGER.log(Level.FINE, "analyzer.AssemblyAnalyzer.grokassembly.deployed", grokAssemblyExe.getPath());
    -  209  0
             } catch (IOException ioe) {
    -  210  0
                 this.setEnabled(false);
    -  211  0
                 LOGGER.log(Level.WARNING, "analyzer.AssemblyAnalyzer.grokassembly.notdeployed", ioe.getMessage());
    -  212  0
                 throw new AnalysisException("Could not extract GrokAssembly.exe", ioe);
    -  213   -
             } finally {
    -  214  5
                 if (fos != null) {
    -  215   -
                     try {
    -  216  5
                         fos.close();
    -  217  0
                     } catch (Throwable e) {
    -  218  0
                         LOGGER.fine("Error closing output stream");
    -  219  5
                     }
    -  220   -
                 }
    -  221  5
                 if (is != null) {
    -  222   -
                     try {
    -  223  5
                         is.close();
    -  224  0
                     } catch (Throwable e) {
    -  225  0
                         LOGGER.fine("Error closing input stream");
    -  226  5
                     }
    -  227   -
                 }
    -  228   -
             }
    -  229   -
     
    -  230   -
             // Now, need to see if GrokAssembly actually runs from this location.
    -  231  5
             final List<String> args = buildArgumentList();
    -  232  5
             BufferedReader rdr = null;
    -  233   -
             try {
    -  234  5
                 final ProcessBuilder pb = new ProcessBuilder(args);
    -  235  5
                 final Process p = pb.start();
    -  236   -
                 // Try evacuating the error stream
    -  237  5
                 rdr = new BufferedReader(new InputStreamReader(p.getErrorStream(), "UTF-8"));
    -  238   -
                 // CHECKSTYLE:OFF
    -  239  5
                 while (rdr.ready() && rdr.readLine() != null) {
    -  240   -
                     // We expect this to complain
    -  241   -
                 }
    -  242   -
                 // CHECKSTYLE:ON
    -  243  5
                 final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(p.getInputStream());
    -  244  5
                 final XPath xpath = XPathFactory.newInstance().newXPath();
    -  245  5
                 final String error = xpath.evaluate("/assembly/error", doc);
    -  246  5
                 if (p.waitFor() != 1 || error == null || "".equals(error)) {
    -  247  0
                     LOGGER.warning("An error occurred with the .NET AssemblyAnalyzer, please see the log for more details.");
    -  248  0
                     LOGGER.fine("GrokAssembly.exe is not working properly");
    -  249  0
                     grokAssemblyExe = null;
    -  250  0
                     this.setEnabled(false);
    -  251  0
                     throw new AnalysisException("Could not execute .NET AssemblyAnalyzer");
    -  252   -
                 }
    -  253  0
             } catch (Throwable e) {
    -  254  0
                 if (e instanceof AnalysisException) {
    -  255  0
                     throw (AnalysisException) e;
    -  256  
                 } else {
    -  257  0
                     LOGGER.warning("analyzer.AssemblyAnalyzer.grokassembly.initialization.failed");
    -  258  0
                     LOGGER.log(Level.FINE, "analyzer.AssemblyAnalyzer.grokassembly.initialization.message", e.getMessage());
    -  259  0
                     this.setEnabled(false);
    -  260  0
                     throw new AnalysisException("An error occured with the .NET AssemblyAnalyzer", e);
    -  261   +  99  0
                     args.add("mono");
    +  100  
                 }
    -  262   -
             } finally {
    -  263  5
                 if (rdr != null) {
    -  264   -
                     try {
    -  265  5
                         rdr.close();
    -  266  0
                     } catch (IOException ex) {
    -  267  0
                         LOGGER.log(Level.FINEST, "ignore", ex);
    -  268  5
                     }
    -  269   -
                 }
    -  270   +  101  
             }
    -  271  5
             builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
    -  272  5
         }
    -  273   +  102  64
             args.add(grokAssemblyExe.getPath());
    +  103  
     
    -  274   +  104  64
             return args;
    +  105   +
         }
    +  106   +
     
    +  107   +
         /**
    +  108   +
          * Performs the analysis on a single Dependency.
    +  109   +
          *
    +  110   +
          * @param dependency the dependency to analyze
    +  111   +
          * @param engine the engine to perform the analysis under
    +  112   +
          * @throws AnalysisException if anything goes sideways
    +  113   +
          */
    +  114  
         @Override
    -  275   -
         public void close() throws Exception {
    -  276  6
             super.close();
    -  277   +  115   +
         public void analyzeFileType(Dependency dependency, Engine engine)
    +  116   +
                 throws AnalysisException {
    +  117  24
             if (grokAssemblyExe == null) {
    +  118  0
                 LOGGER.warn("GrokAssembly didn't get deployed");
    +  119  0
                 return;
    +  120   +
             }
    +  121   +
     
    +  122  24
             final List<String> args = buildArgumentList();
    +  123  24
             args.add(dependency.getActualFilePath());
    +  124  24
             final ProcessBuilder pb = new ProcessBuilder(args);
    +  125  24
             BufferedReader rdr = null;
    +  126  24
             Document doc = null;
    +  127  
             try {
    -  278  6
                 if (grokAssemblyExe != null && !grokAssemblyExe.delete()) {
    -  279  0
                     grokAssemblyExe.deleteOnExit();
    +  128  24
                 final Process proc = pb.start();
    +  129   +
                 // Try evacuating the error stream
    +  130  24
                 rdr = new BufferedReader(new InputStreamReader(proc.getErrorStream(), "UTF-8"));
    +  131  24
                 String line = null;
    +  132   +
                 // CHECKSTYLE:OFF
    +  133  24
                 while (rdr.ready() && (line = rdr.readLine()) != null) {
    +  134  0
                     LOGGER.warn("Error from GrokAssembly: {}", line);
    +  135   +
                 }
    +  136   +
                 // CHECKSTYLE:ON
    +  137  24
                 int rc = 0;
    +  138  24
                 doc = builder.parse(proc.getInputStream());
    +  139   +
     
    +  140   +
                 try {
    +  141  24
                     rc = proc.waitFor();
    +  142  0
                 } catch (InterruptedException ie) {
    +  143   +
                     return;
    +  144  24
                 }
    +  145  24
                 if (rc == 3) {
    +  146  0
                     LOGGER.debug("{} is not a .NET assembly or executable and as such cannot be analyzed by dependency-check",
    +  147   +
                             dependency.getActualFilePath());
    +  148   +
                     return;
    +  149  24
                 } else if (rc != 0) {
    +  150  8
                     LOGGER.warn("Return code {} from GrokAssembly", rc);
    +  151   +
                 }
    +  152   +
     
    +  153  24
                 final XPath xpath = XPathFactory.newInstance().newXPath();
    +  154   +
     
    +  155   +
                 // First, see if there was an error
    +  156  24
                 final String error = xpath.evaluate("/assembly/error", doc);
    +  157  24
                 if (error != null && !"".equals(error)) {
    +  158  8
                     throw new AnalysisException(error);
    +  159   +
                 }
    +  160   +
     
    +  161  16
                 final String version = xpath.evaluate("/assembly/version", doc);
    +  162  16
                 if (version != null) {
    +  163  16
                     dependency.getVersionEvidence().addEvidence(new Evidence("grokassembly", "version",
    +  164   +
                             version, Confidence.HIGHEST));
    +  165   +
                 }
    +  166   +
     
    +  167  16
                 final String vendor = xpath.evaluate("/assembly/company", doc);
    +  168  16
                 if (vendor != null) {
    +  169  16
                     dependency.getVendorEvidence().addEvidence(new Evidence("grokassembly", "vendor",
    +  170   +
                             vendor, Confidence.HIGH));
    +  171   +
                 }
    +  172   +
     
    +  173  16
                 final String product = xpath.evaluate("/assembly/product", doc);
    +  174  16
                 if (product != null) {
    +  175  16
                     dependency.getProductEvidence().addEvidence(new Evidence("grokassembly", "product",
    +  176   +
                             product, Confidence.HIGH));
    +  177   +
                 }
    +  178   +
     
    +  179  0
             } catch (IOException ioe) {
    +  180  0
                 throw new AnalysisException(ioe);
    +  181  0
             } catch (SAXException saxe) {
    +  182  0
                 throw new AnalysisException("Couldn't parse GrokAssembly result", saxe);
    +  183  0
             } catch (XPathExpressionException xpe) {
    +  184   +
                 // This shouldn't happen
    +  185  0
                 throw new AnalysisException(xpe);
    +  186   +
             } finally {
    +  187  24
                 if (rdr != null) {
    +  188   +
                     try {
    +  189  24
                         rdr.close();
    +  190  0
                     } catch (IOException ex) {
    +  191  0
                         LOGGER.debug("ignore", ex);
    +  192  32
                     }
    +  193   +
                 }
    +  194   +
             }
    +  195  16
         }
    +  196   +
     
    +  197   +
         /**
    +  198   +
          * Initialize the analyzer. In this case, extract GrokAssembly.exe to a temporary location.
    +  199   +
          *
    +  200   +
          * @throws Exception if anything goes wrong
    +  201   +
          */
    +  202   +
         @Override
    +  203   +
         public void initializeFileTypeAnalyzer() throws Exception {
    +  204  40
             final File tempFile = File.createTempFile("GKA", ".exe", Settings.getTempDirectory());
    +  205  40
             FileOutputStream fos = null;
    +  206  40
             InputStream is = null;
    +  207   +
             try {
    +  208  40
                 fos = new FileOutputStream(tempFile);
    +  209  40
                 is = AssemblyAnalyzer.class.getClassLoader().getResourceAsStream("GrokAssembly.exe");
    +  210  40
                 final byte[] buff = new byte[4096];
    +  211  40
                 int bread = -1;
    +  212  120
                 while ((bread = is.read(buff)) >= 0) {
    +  213  80
                     fos.write(buff, 0, bread);
    +  214   +
                 }
    +  215  40
                 grokAssemblyExe = tempFile;
    +  216   +
                 // Set the temp file to get deleted when we're done
    +  217  40
                 grokAssemblyExe.deleteOnExit();
    +  218  40
                 LOGGER.debug("Extracted GrokAssembly.exe to {}", grokAssemblyExe.getPath());
    +  219  0
             } catch (IOException ioe) {
    +  220  0
                 this.setEnabled(false);
    +  221  0
                 LOGGER.warn("Could not extract GrokAssembly.exe: {}", ioe.getMessage());
    +  222  0
                 throw new AnalysisException("Could not extract GrokAssembly.exe", ioe);
    +  223   +
             } finally {
    +  224  40
                 if (fos != null) {
    +  225   +
                     try {
    +  226  40
                         fos.close();
    +  227  0
                     } catch (Throwable e) {
    +  228  0
                         LOGGER.debug("Error closing output stream");
    +  229  40
                     }
    +  230   +
                 }
    +  231  40
                 if (is != null) {
    +  232   +
                     try {
    +  233  40
                         is.close();
    +  234  0
                     } catch (Throwable e) {
    +  235  0
                         LOGGER.debug("Error closing input stream");
    +  236  40
                     }
    +  237   +
                 }
    +  238   +
             }
    +  239   +
     
    +  240   +
             // Now, need to see if GrokAssembly actually runs from this location.
    +  241  40
             final List<String> args = buildArgumentList();
    +  242  40
             BufferedReader rdr = null;
    +  243   +
             try {
    +  244  40
                 final ProcessBuilder pb = new ProcessBuilder(args);
    +  245  40
                 final Process p = pb.start();
    +  246   +
                 // Try evacuating the error stream
    +  247  40
                 rdr = new BufferedReader(new InputStreamReader(p.getErrorStream(), "UTF-8"));
    +  248   +
                 // CHECKSTYLE:OFF
    +  249  40
                 while (rdr.ready() && rdr.readLine() != null) {
    +  250   +
                     // We expect this to complain
    +  251   +
                 }
    +  252   +
                 // CHECKSTYLE:ON
    +  253  40
                 final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(p.getInputStream());
    +  254  40
                 final XPath xpath = XPathFactory.newInstance().newXPath();
    +  255  40
                 final String error = xpath.evaluate("/assembly/error", doc);
    +  256  40
                 if (p.waitFor() != 1 || error == null || "".equals(error)) {
    +  257  0
                     LOGGER.warn("An error occurred with the .NET AssemblyAnalyzer, please see the log for more details.");
    +  258  0
                     LOGGER.debug("GrokAssembly.exe is not working properly");
    +  259  0
                     grokAssemblyExe = null;
    +  260  0
                     this.setEnabled(false);
    +  261  0
                     throw new AnalysisException("Could not execute .NET AssemblyAnalyzer");
    +  262   +
                 }
    +  263  0
             } catch (Throwable e) {
    +  264  0
                 if (e instanceof AnalysisException) {
    +  265  0
                     throw (AnalysisException) e;
    +  266   +
                 } else {
    +  267  0
                     LOGGER.warn("An error occurred with the .NET AssemblyAnalyzer;\n"
    +  268   +
                             + "this can be ignored unless you are scanning .NET DLLs. Please see the log for more details.");
    +  269  0
                     LOGGER.debug("Could not execute GrokAssembly {}", e.getMessage());
    +  270  0
                     this.setEnabled(false);
    +  271  0
                     throw new AnalysisException("An error occured with the .NET AssemblyAnalyzer", e);
    +  272   +
                 }
    +  273   +
             } finally {
    +  274  40
                 if (rdr != null) {
    +  275   +
                     try {
    +  276  40
                         rdr.close();
    +  277  0
                     } catch (IOException ex) {
    +  278  0
                         LOGGER.trace("ignore", ex);
    +  279  40
                     }
     280  
                 }
    -  281  0
             } catch (SecurityException se) {
    -  282  0
                 LOGGER.fine("analyzer.AssemblyAnalyzer.grokassembly.notdeleted");
    -  283  6
             }
    -  284  6
         }
    +  281   +
             }
    +  282  40
             builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
    +  283  40
         }
    +  284   +
     
     285   -
     
    +
         /**
     286   -
         /**
    +
          * Removes resources used from the local file system.
     287   -
          * Gets the set of extensions supported by this analyzer.
    +
          *
     288   -
          *
    +
          * @throws Exception thrown if there is a problem closing the analyzer
     289   -
          * @return the list of supported extensions
    +
          */
     290   -
          */
    +
         @Override
     291   -
         @Override
    -  292   -
         public Set<String> getSupportedExtensions() {
    -  293  853
             return SUPPORTED_EXTENSIONS;
    -  294   -
         }
    -  295   -
     
    +
         public void close() throws Exception {
    +  292  48
             super.close();
    +  293   +
             try {
    +  294  48
                 if (grokAssemblyExe != null && !grokAssemblyExe.delete()) {
    +  295  0
                     grokAssemblyExe.deleteOnExit();
     296   -
         /**
    -  297   -
          * Gets this analyzer's name.
    -  298   -
          *
    -  299   -
          * @return the analyzer name
    -  300   -
          */
    +
                 }
    +  297  0
             } catch (SecurityException se) {
    +  298  0
                 LOGGER.debug("Can't delete temporary GrokAssembly.exe");
    +  299  48
             }
    +  300  48
         }
     301   -
         @Override
    +
     
     302   -
         public String getName() {
    -  303  5
             return ANALYZER_NAME;
    +
         /**
    +  303   +
          * The File Filter used to filter supported extensions.
     304   -
         }
    -  305   -
     
    +
          */
    +  305  8
         private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(
     306   -
         /**
    +
                 SUPPORTED_EXTENSIONS).build();
     307   -
          * Returns the phase this analyzer runs under.
    -  308   -
          *
    -  309   -
          * @return the phase this runs under
    -  310   -
          */
    -  311   -
         @Override
    -  312   -
         public AnalysisPhase getAnalysisPhase() {
    -  313  1
             return ANALYSIS_PHASE;
    -  314   -
         }
    -  315  
     
    -  316   -
         /**
    -  317   -
          * Returns the key used in the properties file to reference the analyzer's enabled property.
    -  318   -
          *
    -  319   -
          * @return the analyzer's enabled property setting key
    -  320   -
          */
    -  321   +  308  
         @Override
    -  322   -
         protected String getAnalyzerEnabledSettingKey() {
    -  323  7
             return Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED;
    -  324   +  309   +
         protected FileFilter getFileFilter() {
    +  310  6864
             return FILTER;
    +  311  
         }
    +  312   +
     
    +  313   +
         /**
    +  314   +
          * Gets this analyzer's name.
    +  315   +
          *
    +  316   +
          * @return the analyzer name
    +  317   +
          */
    +  318   +
         @Override
    +  319   +
         public String getName() {
    +  320  40
             return ANALYZER_NAME;
    +  321   +
         }
    +  322   +
     
    +  323   +
         /**
    +  324   +
          * Returns the phase this analyzer runs under.
     325   +
          *
    +  326   +
          * @return the phase this runs under
    +  327   +
          */
    +  328   +
         @Override
    +  329   +
         public AnalysisPhase getAnalysisPhase() {
    +  330  16
             return ANALYSIS_PHASE;
    +  331   +
         }
    +  332   +
     
    +  333   +
         /**
    +  334   +
          * Returns the key used in the properties file to reference the analyzer's enabled property.
    +  335   +
          *
    +  336   +
          * @return the analyzer's enabled property setting key
    +  337   +
          */
    +  338   +
         @Override
    +  339   +
         protected String getAnalyzerEnabledSettingKey() {
    +  340  64
             return Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED;
    +  341   +
         }
    +  342  
     }
    - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AutoconfAnalyzer.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AutoconfAnalyzer.html new file mode 100644 index 000000000..c7c7e0d00 --- /dev/null +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.AutoconfAnalyzer.html @@ -0,0 +1,515 @@ + + + + +Coverage Report + + + + +
    Coverage Report - org.owasp.dependencycheck.analyzer.AutoconfAnalyzer
    +
     
    + + + + +
    Classes in this File Line Coverage Branch Coverage Complexity
    AutoconfAnalyzer
    92%
    62/67
    76%
    26/34
    3.111
    +
     
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
     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) 2015 Institute for Defense Analyses. All Rights Reserved.
     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;
     28  
     import org.owasp.dependencycheck.utils.UrlStringUtils;
     29  
     
     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 <dvisser@ida.org>
     43  
      * @see <a href="https://www.gnu.org/software/autoconf/">Autoconf - GNU Project - Free Software Foundation (FSF)</a>
     44  
      */
     45  72
     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  8
         private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
     71  
     
     72  
         /**
     73  
          * The set of file extensions supported by this analyzer.
     74  
          */
     75  8
         private static final String[] EXTENSIONS = {"ac", "in"};
     76  
     
     77  
         /**
     78  
          * Matches AC_INIT variables in the output configure script.
     79  
          */
     80  8
         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  8
             final String param = "\\[{0,2}(.+?)\\]{0,2}";
     91  8
             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  8
             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  8
         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  6848
             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  40
             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  16
             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  72
             return Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED;
     150  
         }
     151  
     
     152  
         @Override
     153  
         protected void analyzeFileType(Dependency dependency, Engine engine)
     154  
                 throws AnalysisException {
     155  32
             final File actualFile = dependency.getActualFile();
     156  32
             final String name = actualFile.getName();
     157  32
             if (name.startsWith(CONFIGURE)) {
     158  32
                 final File parent = actualFile.getParentFile();
     159  32
                 final String parentName = parent.getName();
     160  32
                 dependency.setDisplayFileName(parentName + "/" + name);
     161  32
                 final boolean isOutputScript = CONFIGURE.equals(name);
     162  32
                 if (isOutputScript || CONFIGURE_AC.equals(name)
     163  
                         || CONFIGURE_IN.equals(name)) {
     164  32
                     final String contents = getFileContents(actualFile);
     165  32
                     if (!contents.isEmpty()) {
     166  32
                         if (isOutputScript) {
     167  16
                             extractConfigureScriptEvidence(dependency, name,
     168  
                                     contents);
     169  
                         } else {
     170  16
                             gatherEvidence(dependency, name, contents);
     171  
                         }
     172  
                     }
     173  
                 }
     174  32
             } else {
     175  
                 // copy, alter and set in case some other thread is iterating over
     176  0
                 final List<Dependency> deps = new ArrayList<Dependency>(
     177  
                         engine.getDependencies());
     178  0
                 deps.remove(dependency);
     179  0
                 engine.setDependencies(deps);
     180  
             }
     181  32
         }
     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  16
             final Matcher matcher = PACKAGE_VAR.matcher(contents);
     193  160
             while (matcher.find()) {
     194  144
                 final String variable = matcher.group(1);
     195  144
                 final String value = matcher.group(2);
     196  144
                 if (!value.isEmpty()) {
     197  112
                     if (variable.endsWith("NAME")) {
     198  32
                         dependency.getProductEvidence().addEvidence(name, variable,
     199  
                                 value, Confidence.HIGHEST);
     200  80
                     } else if ("VERSION".equals(variable)) {
     201  16
                         dependency.getVersionEvidence().addEvidence(name, variable,
     202  
                                 value, Confidence.HIGHEST);
     203  64
                     } else if ("BUGREPORT".equals(variable)) {
     204  8
                         dependency.getVendorEvidence().addEvidence(name, variable,
     205  
                                 value, Confidence.HIGH);
     206  56
                     } else if ("URL".equals(variable)) {
     207  8
                         dependency.getVendorEvidence().addEvidence(name, variable,
     208  
                                 value, Confidence.HIGH);
     209  
                     }
     210  
                 }
     211  144
             }
     212  16
         }
     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  32
             String contents = "";
     224  
             try {
     225  32
                 contents = FileUtils.readFileToString(actualFile).trim();
     226  0
             } catch (IOException e) {
     227  0
                 throw new AnalysisException(
     228  
                         "Problem occured while reading dependency file.", e);
     229  32
             }
     230  32
             return contents;
     231  
         }
     232  
     
     233  
         /**
     234  
          * Gathers evidence from a given file
     235  
          *
     236  
          * @param dependency the dependency to add evidence to
     237  
          * @param name the source of the evidence
     238  
          * @param contents the evidence to analyze
     239  
          */
     240  
         private void gatherEvidence(Dependency dependency, final String name,
     241  
                 String contents) {
     242  16
             final Matcher matcher = AC_INIT_PATTERN.matcher(contents);
     243  16
             if (matcher.find()) {
     244  16
                 final EvidenceCollection productEvidence = dependency
     245  
                         .getProductEvidence();
     246  16
                 productEvidence.addEvidence(name, "Package", matcher.group(1),
     247  
                         Confidence.HIGHEST);
     248  16
                 dependency.getVersionEvidence().addEvidence(name,
     249  
                         "Package Version", matcher.group(2), Confidence.HIGHEST);
     250  16
                 final EvidenceCollection vendorEvidence = dependency
     251  
                         .getVendorEvidence();
     252  16
                 if (null != matcher.group(3)) {
     253  16
                     vendorEvidence.addEvidence(name, "Bug report address",
     254  
                             matcher.group(4), Confidence.HIGH);
     255  
                 }
     256  16
                 if (null != matcher.group(5)) {
     257  8
                     productEvidence.addEvidence(name, "Tarname", matcher.group(6),
     258  
                             Confidence.HIGH);
     259  
                 }
     260  16
                 if (null != matcher.group(7)) {
     261  8
                     final String url = matcher.group(8);
     262  8
                     if (UrlStringUtils.isUrl(url)) {
     263  8
                         vendorEvidence.addEvidence(name, "URL", url,
     264  
                                 Confidence.HIGH);
     265  
                     }
     266  
                 }
     267  
             }
     268  16
         }
     269  
     
     270  
         /**
     271  
          * Initializes the file type analyzer.
     272  
          *
     273  
          * @throws Exception thrown if there is an exception during initialization
     274  
          */
     275  
         @Override
     276  
         protected void initializeFileTypeAnalyzer() throws Exception {
     277  
             // No initialization needed.
     278  48
         }
     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 new file mode 100644 index 000000000..4d5cf9311 --- /dev/null +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.CMakeAnalyzer.html @@ -0,0 +1,393 @@ + + + + +Coverage Report + + + + +
    Coverage Report - org.owasp.dependencycheck.analyzer.CMakeAnalyzer
    +
     
    + + + + +
    Classes in this File Line Coverage Branch Coverage Complexity
    CMakeAnalyzer
    93%
    59/63
    80%
    8/10
    2
    +
     
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
     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) 2015 Institute for Defense Analyses. All Rights Reserved.
     17  
      */
     18  
     package org.owasp.dependencycheck.analyzer;
     19  
     
     20  
     import org.apache.commons.io.FileUtils;
     21  
     import org.apache.commons.lang.StringUtils;
     22  
     import org.owasp.dependencycheck.Engine;
     23  
     import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
     24  
     import org.owasp.dependencycheck.dependency.Confidence;
     25  
     import org.owasp.dependencycheck.dependency.Dependency;
     26  
     import org.owasp.dependencycheck.utils.Checksum;
     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.File;
     33  
     import java.io.FileFilter;
     34  
     import java.io.IOException;
     35  
     import java.security.MessageDigest;
     36  
     import java.security.NoSuchAlgorithmException;
     37  
     import java.util.regex.Matcher;
     38  
     import java.util.regex.Pattern;
     39  
     
     40  
     /**
     41  
      * <p>
     42  
      * Used to analyze CMake build files, and collect information that can be used to determine the associated CPE.</p>
     43  
      * <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 <dvisser@ida.org>
     51  
      */
     52  64
     public class CMakeAnalyzer extends AbstractFileTypeAnalyzer {
     53  
     
     54  
         /**
     55  
          * The logger.
     56  
          */
     57  8
         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  8
         private static final Pattern PROJECT = Pattern.compile(
     66  
                 "^ *project *\\([ \\n]*(\\w+)[ \\n]*.*?\\)", REGEX_OPTIONS);
     67  
     
     68  
         // Group 1: Product
     69  
         // Group 2: Version
     70  8
         private static final Pattern SET_VERSION = Pattern
     71  
                 .compile(
     72  
                         "^ *set\\s*\\(\\s*(\\w+)_version\\s+\"?(\\d+(?:\\.\\d+)+)[\\s\"]?\\)",
     73  
                         REGEX_OPTIONS);
     74  
     
     75  
         /**
     76  
          * Detects files that can be analyzed.
     77  
          */
     78  8
         private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(".cmake")
     79  
                 .addFilenames("CMakeLists.txt").build();
     80  
     
     81  
         /**
     82  
          * A reference to SHA1 message digest.
     83  
          */
     84  8
         private static MessageDigest sha1 = null;
     85  
     
     86  
         static {
     87  
             try {
     88  8
                 sha1 = MessageDigest.getInstance("SHA1");
     89  0
             } catch (NoSuchAlgorithmException e) {
     90  0
                 LOGGER.error(e.getMessage());
     91  8
             }
     92  8
         }
     93  
     
     94  
         /**
     95  
          * Returns the name of the CMake analyzer.
     96  
          *
     97  
          * @return the name of the analyzer
     98  
          *
     99  
          */
     100  
         @Override
     101  
         public String getName() {
     102  40
             return "CMake Analyzer";
     103  
         }
     104  
     
     105  
         /**
     106  
          * Tell that we are used for information collection.
     107  
          *
     108  
          * @return INFORMATION_COLLECTION
     109  
          */
     110  
         @Override
     111  
         public AnalysisPhase getAnalysisPhase() {
     112  16
             return AnalysisPhase.INFORMATION_COLLECTION;
     113  
         }
     114  
     
     115  
         /**
     116  
          * Returns the set of supported file extensions.
     117  
          *
     118  
          * @return the set of supported file extensions
     119  
          */
     120  
         @Override
     121  
         protected FileFilter getFileFilter() {
     122  6840
             return FILTER;
     123  
         }
     124  
     
     125  
         /**
     126  
          * No-op initializer implementation.
     127  
          *
     128  
          * @throws Exception never thrown
     129  
          */
     130  
         @Override
     131  
         protected void initializeFileTypeAnalyzer() throws Exception {
     132  
             // Nothing to do here.
     133  40
         }
     134  
     
     135  
         /**
     136  
          * Analyzes python packages and adds evidence to the dependency.
     137  
          *
     138  
          * @param dependency the dependency being analyzed
     139  
          * @param engine the engine being used to perform the scan
     140  
          * @throws AnalysisException thrown if there is an unrecoverable error analyzing the dependency
     141  
          */
     142  
         @Override
     143  
         protected void analyzeFileType(Dependency dependency, Engine engine)
     144  
                 throws AnalysisException {
     145  24
             final File file = dependency.getActualFile();
     146  24
             final String parentName = file.getParentFile().getName();
     147  24
             final String name = file.getName();
     148  24
             dependency.setDisplayFileName(String.format("%s%c%s", parentName, File.separatorChar, name));
     149  
             String contents;
     150  
             try {
     151  24
                 contents = FileUtils.readFileToString(file).trim();
     152  0
             } catch (IOException e) {
     153  0
                 throw new AnalysisException(
     154  
                         "Problem occurred while reading dependency file.", e);
     155  24
             }
     156  
     
     157  24
             if (StringUtils.isNotBlank(contents)) {
     158  24
                 final Matcher m = PROJECT.matcher(contents);
     159  24
                 int count = 0;
     160  40
                 while (m.find()) {
     161  16
                     count++;
     162  16
                     LOGGER.debug(String.format(
     163  
                             "Found project command match with %d groups: %s",
     164  
                             m.groupCount(), m.group(0)));
     165  16
                     final String group = m.group(1);
     166  16
                     LOGGER.debug("Group 1: " + group);
     167  16
                     dependency.getProductEvidence().addEvidence(name, "Project",
     168  
                             group, Confidence.HIGH);
     169  16
                 }
     170  24
                 LOGGER.debug(String.format("Found %d matches.", count));
     171  24
                 analyzeSetVersionCommand(dependency, engine, contents);
     172  
             }
     173  24
         }
     174  
     
     175  
         private void analyzeSetVersionCommand(Dependency dependency, Engine engine, String contents) {
     176  24
             final Dependency orig = dependency;
     177  24
             final Matcher m = SET_VERSION.matcher(contents);
     178  24
             int count = 0;
     179  64
             while (m.find()) {
     180  40
                 count++;
     181  40
                 LOGGER.debug(String.format(
     182  
                         "Found project command match with %d groups: %s",
     183  
                         m.groupCount(), m.group(0)));
     184  40
                 String product = m.group(1);
     185  40
                 final String version = m.group(2);
     186  40
                 LOGGER.debug("Group 1: " + product);
     187  40
                 LOGGER.debug("Group 2: " + version);
     188  40
                 final String aliasPrefix = "ALIASOF_";
     189  40
                 if (product.startsWith(aliasPrefix)) {
     190  40
                     product = product.replaceFirst(aliasPrefix, "");
     191  
                 }
     192  40
                 if (count > 1) {
     193  
                     //TODO - refactor so we do not assign to the parameter (checkstyle)
     194  32
                     dependency = new Dependency(orig.getActualFile());
     195  32
                     dependency.setDisplayFileName(String.format("%s:%s", orig.getDisplayFileName(), product));
     196  32
                     final String filePath = String.format("%s:%s", orig.getFilePath(), product);
     197  32
                     dependency.setFilePath(filePath);
     198  
     
     199  
                     // prevents coalescing into the dependency provided by engine
     200  32
                     dependency.setSha1sum(Checksum.getHex(sha1.digest(filePath.getBytes())));
     201  32
                     engine.getDependencies().add(dependency);
     202  
                 }
     203  40
                 final String source = dependency.getDisplayFileName();
     204  40
                 dependency.getProductEvidence().addEvidence(source, "Product",
     205  
                         product, Confidence.MEDIUM);
     206  40
                 dependency.getVersionEvidence().addEvidence(source, "Version",
     207  
                         version, Confidence.MEDIUM);
     208  40
             }
     209  24
             LOGGER.debug(String.format("Found %d matches.", count));
     210  24
         }
     211  
     
     212  
         @Override
     213  
         protected String getAnalyzerEnabledSettingKey() {
     214  64
             return Settings.KEYS.ANALYZER_CMAKE_ENABLED;
     215  
         }
     216  
     }
    + + + + 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 7a542ceed..d5e2b8707 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 @@
     
    - + @@ -74,53 +74,53 @@ - - - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + + @@ -135,7 +135,7 @@ - + @@ -144,7 +144,7 @@ - + @@ -227,7 +227,7 @@ - + @@ -246,7 +246,7 @@ - + @@ -265,8 +265,8 @@ - - + + @@ -285,19 +285,19 @@ - - - - - + + + + + - + - + - - + + @@ -310,211 +310,211 @@ - - - + + + + - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - + - + - - - - - - - + + + + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + - + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - + + + + + + + @@ -553,23 +553,23 @@ - - - + + + - + - - + + - + @@ -596,47 +596,47 @@ - + - + - + - + - - - - - - - - - + + + + + + + + + - - - + + + - - + + - - + + @@ -655,7 +655,7 @@ - + @@ -676,15 +676,15 @@ - + - - - + + + @@ -707,579 +707,583 @@ - + - + + + + + - - - - - + + - - - + + - + - + - + - + - + - + - + - + + + + + - - - + + + - - - - - - - - + + + + - + + + + + - - - - - - - - + + + + + + + + - + - - - - - - - + + + + + + + - + - - - + + + - - - - - - - - - + + + + + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - + - + - + + + + + - - - - - - - - - - + + + + + + + + + + - - - - - - - + + + + + + + - - - - - + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - + + + + - + + + + + - - - - - - + + + + + + - - - + + + - - - - - - + + + + + + - - - + + + - - - + + + - - - - - - - + + + + + + + - - - - - - + + + + + + - - - + + + - - - - - - + + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - - + + - + - - - - - - - - - - - - - - - + + + - - - - - - - - + + - - - + + + - - - - - + + - - - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Classes in this File Line Coverage Branch Coverage Complexity
    CPEAnalyzer
    77%
    172/221
    69%
    92/132
    4.571
    CPEAnalyzer
    80%
    178/221
    73%
    97/132
    4.571
    CPEAnalyzer$IdentifierConfidence
    100%
    4/4
    N/A
    4.571
    CPEAnalyzer$IdentifierMatch
    38%
    15/39
    16%
    4/24
    4.571
     27  
     import java.util.StringTokenizer;
     28  
     import java.util.logging.Level;
     29  
     import java.util.logging.Logger;
     30  
     import org.apache.lucene.document.Document;
     31  
     29  
     import org.apache.lucene.index.CorruptIndexException;
     32  
     30  
     import org.apache.lucene.queryparser.classic.ParseException;
     33  
     31  
     import org.apache.lucene.search.ScoreDoc;
     34  
     32  
     import org.apache.lucene.search.TopDocs;
     35  
     33  
     import org.owasp.dependencycheck.Engine;
     36  
     34  
     import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
     37  
     35  
     import org.owasp.dependencycheck.data.cpe.CpeMemoryIndex;
     38  
     36  
     import org.owasp.dependencycheck.data.cpe.Fields;
     39  
     37  
     import org.owasp.dependencycheck.data.cpe.IndexEntry;
     40  
     38  
     import org.owasp.dependencycheck.data.cpe.IndexException;
     41  
     39  
     import org.owasp.dependencycheck.data.lucene.LuceneUtils;
     42  
     40  
     import org.owasp.dependencycheck.data.nvdcve.CveDB;
     43  
     41  
     import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
     44  
     42  
     import org.owasp.dependencycheck.dependency.Confidence;
     45  
     43  
     import org.owasp.dependencycheck.dependency.Dependency;
     46  
     44  
     import org.owasp.dependencycheck.dependency.Evidence;
     47  
     45  
     import org.owasp.dependencycheck.dependency.EvidenceCollection;
     48  
     46  
     import org.owasp.dependencycheck.dependency.Identifier;
     49  
     47  
     import org.owasp.dependencycheck.dependency.VulnerableSoftware;
     50  
     48  
     import org.owasp.dependencycheck.utils.DependencyVersion;
     51  
     49  
     import org.owasp.dependencycheck.utils.DependencyVersionUtil;
     50  
     import org.slf4j.Logger;
     51  
     import org.slf4j.LoggerFactory;
     52  
     
     53  
      * @author Jeremy Long
     58  
      */
     59  2
     public class CPEAnalyzer implements Analyzer {
     59  24
     public class CPEAnalyzer implements Analyzer {
     60  
     
     61  
          * The Logger.
     63  
          */
     64  1
         private static final Logger LOGGER = Logger.getLogger(CPEAnalyzer.class.getName());
     64  8
         private static final Logger LOGGER = LoggerFactory.getLogger(CPEAnalyzer.class);
     65  
         /**
     66  
         @Override
     105  
         public String getName() {
     106  4
             return "CPE Analyzer";
     106  32
             return "CPE Analyzer";
     107  
         }
     108  
         @Override
     115  
         public AnalysisPhase getAnalysisPhase() {
     116  1
             return AnalysisPhase.IDENTIFIER_ANALYSIS;
     116  16
             return AnalysisPhase.IDENTIFIER_ANALYSIS;
     117  
         }
     118  
         @Override
     125  
         public void initialize() throws Exception {
     126  1
             this.open();
     127  1
         }
     126  8
             this.open();
     127  8
         }
     128  
     
     129  
          */
     136  
         public void open() throws IOException, DatabaseException {
     137  1
             LOGGER.log(Level.FINE, "Opening the CVE Database");
     138  1
             cve = new CveDB();
     139  1
             cve.open();
     140  1
             LOGGER.log(Level.FINE, "Creating the Lucene CPE Index");
     141  1
             cpe = CpeMemoryIndex.getInstance();
     137  8
             LOGGER.debug("Opening the CVE Database");
     138  8
             cve = new CveDB();
     139  8
             cve.open();
     140  8
             LOGGER.debug("Creating the Lucene CPE Index");
     141  8
             cpe = CpeMemoryIndex.getInstance();
     142  
             try {
     143  1
                 cpe.open(cve);
     143  8
                 cpe.open(cve);
     144  0
             } catch (IndexException ex) {
     145  0
                 LOGGER.log(Level.FINE, "IndexException", ex);
     145  0
                 LOGGER.debug("IndexException", ex);
     146  0
                 throw new DatabaseException(ex);
     147  1
             }
     148  1
         }
     147  8
             }
     148  8
         }
     149  
     
     150  
         @Override
     154  
         public void close() {
     155  1
             if (cpe != null) {
     156  1
                 cpe.close();
     157  
     155  8
             if (cpe != null) {
     156  8
                 cpe.close();
     157  8
                 cpe = null;
     158  
             }
     158  1
             if (cve != null) {
     159  1
                 cve.close();
     160  
             }
     161  1
         }
     159  8
             if (cve != null) {
     160  8
                 cve.close();
     161  8
                 cve = null;
     162  
     
     163  
         public boolean isOpen() {
     164  0
             return cpe != null && cpe.isOpen();
     165  
         }
     166  
     
     167  
         /**
     168  
          * Searches the data store of CPE entries, trying to identify the CPE for the given dependency based on the evidence contained
     169  
          * within. The dependency passed in is updated with any identified CPE values.
     170  
          *
     171  
          * @param dependency the dependency to search for CPE entries on.
     172  
          * @throws CorruptIndexException is thrown when the Lucene index is corrupt.
     173  
          * @throws IOException is thrown when an IOException occurs.
     174  
          * @throws ParseException is thrown when the Lucene query cannot be parsed.
     175  
          */
     176  
         protected void determineCPE(Dependency dependency) throws CorruptIndexException, IOException, ParseException {
     177  
             //TODO test dojo-war against this. we shold get dojo-toolkit:dojo-toolkit AND dojo-toolkit:toolkit
     178  2
             String vendors = "";
     179  2
             String products = "";
     180  7
             for (Confidence confidence : Confidence.values()) {
     181  6
                 if (dependency.getVendorEvidence().contains(confidence)) {
     182  6
                     vendors = addEvidenceWithoutDuplicateTerms(vendors, dependency.getVendorEvidence(), confidence);
     183  6
                     LOGGER.fine(String.format("vendor search: %s", vendors));
     184  
                 }
     185  6
                 if (dependency.getProductEvidence().contains(confidence)) {
     186  5
                     products = addEvidenceWithoutDuplicateTerms(products, dependency.getProductEvidence(), confidence);
     187  5
                     LOGGER.fine(String.format("product search: %s", products));
     188  
                 }
     189  6
                 if (!vendors.isEmpty() && !products.isEmpty()) {
     190  6
                     final List<IndexEntry> entries = searchCPE(vendors, products, dependency.getProductEvidence().getWeighting(),
     191  
                             dependency.getVendorEvidence().getWeighting());
     192  6
                     if (entries == null) {
     193  0
                         continue;
     194  
                     }
     195  6
                     boolean identifierAdded = false;
     196  6
                     for (IndexEntry e : entries) {
     197  47
                         LOGGER.fine(String.format("Verifying entry: %s", e.toString()));
     198  47
                         if (verifyEntry(e, dependency)) {
     199  2
                             final String vendor = e.getVendor();
     200  2
                             final String product = e.getProduct();
     201  2
                             LOGGER.fine(String.format("identified vendor/product: %s/%s", vendor, product));
     202  2
                             identifierAdded |= determineIdentifiers(dependency, vendor, product, confidence);
     203  
                         }
     204  47
                     }
     205  6
                     if (identifierAdded) {
     206  1
                         break;
     207  
                     }
     208  
                 }
     209  
             }
     210  2
         }
     211  
     163  8
         }
     164  
     
     212  
         /**
     213  
          * Returns the text created by concatenating the text and the values from the EvidenceCollection (filtered for a specific
     214  
          * confidence). This attempts to prevent duplicate terms from being added.<br/<br/> Note, if the evidence is longer then 200
     215  
          * characters it will be truncated.
     216  
          *
     217  
          * @param text the base text.
     218  
          * @param ec an EvidenceCollection
     219  
          * @param confidenceFilter a Confidence level to filter the evidence by.
     220  
          * @return the new evidence text
     221  
          */
     222  
         private String addEvidenceWithoutDuplicateTerms(final String text, final EvidenceCollection ec, Confidence confidenceFilter) {
     223  11
             final String txt = (text == null) ? "" : text;
     224  11
             final StringBuilder sb = new StringBuilder(txt.length() + (20 * ec.size()));
     225  11
             sb.append(' ').append(txt).append(' ');
     226  11
             for (Evidence e : ec.iterator(confidenceFilter)) {
     227  42
                 String value = e.getValue();
     228  
     
     229  
                 //hack to get around the fact that lucene does a really good job of recognizing domains and not
     230  
                 // splitting them. TODO - put together a better lucene analyzer specific to the domain.
     231  42
                 if (value.startsWith("http://")) {
     232  2
                     value = value.substring(7).replaceAll("\\.", " ");
     233  
                 }
     234  42
                 if (value.startsWith("https://")) {
     235  0
                     value = value.substring(8).replaceAll("\\.", " ");
     236  
                 }
     237  42
                 if (sb.indexOf(" " + value + " ") < 0) {
     238  37
                     sb.append(value).append(' ');
     239  
                 }
     240  42
             }
     241  11
             return sb.toString().trim();
     242  
     165  
         public boolean isOpen() {
     166  0
             return cpe != null && cpe.isOpen();
     167  
         }
     243  
     168  
     
     244  
     169  
         /**
     245  
          * <p>
     246  
          * Searches the Lucene CPE index to identify possible CPE entries associated with the supplied vendor, product, and
     247  
          * version.</p>
     248  
     170  
          * Searches the data store of CPE entries, trying to identify the CPE for the given dependency based on the evidence contained
     171  
          * within. The dependency passed in is updated with any identified CPE values.
     172  
          *
     249  
          * <p>
     250  
          * If either the vendorWeightings or productWeightings lists have been populated this data is used to add weighting factors to
     251  
          * the search.</p>
     252  
          *
     253  
          * @param vendor the text used to search the vendor field
     254  
          * @param product the text used to search the product field
     255  
          * @param vendorWeightings a list of strings to use to add weighting factors to the vendor field
     256  
          * @param productWeightings Adds a list of strings that will be used to add weighting factors to the product search
     257  
          * @return a list of possible CPE values
     258  
     173  
          * @param dependency the dependency to search for CPE entries on.
     174  
          * @throws CorruptIndexException is thrown when the Lucene index is corrupt.
     175  
          * @throws IOException is thrown when an IOException occurs.
     176  
          * @throws ParseException is thrown when the Lucene query cannot be parsed.
     177  
          */
     259  
         protected List<IndexEntry> searchCPE(String vendor, String product,
     260  
                 Set<String> vendorWeightings, Set<String> productWeightings) {
     261  
     178  
         protected void determineCPE(Dependency dependency) throws CorruptIndexException, IOException, ParseException {
     179  
             //TODO test dojo-war against this. we shold get dojo-toolkit:dojo-toolkit AND dojo-toolkit:toolkit
     180  16
             String vendors = "";
     181  16
             String products = "";
     182  56
             for (Confidence confidence : Confidence.values()) {
     183  48
                 if (dependency.getVendorEvidence().contains(confidence)) {
     184  40
                     vendors = addEvidenceWithoutDuplicateTerms(vendors, dependency.getVendorEvidence(), confidence);
     185  40
                     LOGGER.debug("vendor search: {}", vendors);
     186  
                 }
     187  48
                 if (dependency.getProductEvidence().contains(confidence)) {
     188  40
                     products = addEvidenceWithoutDuplicateTerms(products, dependency.getProductEvidence(), confidence);
     189  40
                     LOGGER.debug("product search: {}", products);
     190  
                 }
     191  48
                 if (!vendors.isEmpty() && !products.isEmpty()) {
     192  48
                     final List<IndexEntry> entries = searchCPE(vendors, products, dependency.getProductEvidence().getWeighting(),
     193  
                             dependency.getVendorEvidence().getWeighting());
     194  48
                     if (entries == null) {
     195  0
                         continue;
     196  
                     }
     197  48
                     boolean identifierAdded = false;
     198  48
                     for (IndexEntry e : entries) {
     199  344
                         LOGGER.debug("Verifying entry: {}", e);
     200  344
                         if (verifyEntry(e, dependency)) {
     201  24
                             final String vendor = e.getVendor();
     202  24
                             final String product = e.getProduct();
     203  24
                             LOGGER.debug("identified vendor/product: {}/{}", vendor, product);
     204  24
                             identifierAdded |= determineIdentifiers(dependency, vendor, product, confidence);
     205  
                         }
     206  344
                     }
     207  48
                     if (identifierAdded) {
     208  8
                         break;
     209  
                     }
     210  
                 }
     211  
             }
     212  16
         }
     213  
     
     262  6
             final List<IndexEntry> ret = new ArrayList<IndexEntry>(MAX_QUERY_RESULTS);
     214  
         /**
     215  
          * Returns the text created by concatenating the text and the values from the EvidenceCollection (filtered for a specific
     216  
          * confidence). This attempts to prevent duplicate terms from being added.<br/<br/> Note, if the evidence is longer then 200
     217  
          * characters it will be truncated.
     218  
          *
     219  
          * @param text the base text.
     220  
          * @param ec an EvidenceCollection
     221  
          * @param confidenceFilter a Confidence level to filter the evidence by.
     222  
          * @return the new evidence text
     223  
          */
     224  
         private String addEvidenceWithoutDuplicateTerms(final String text, final EvidenceCollection ec, Confidence confidenceFilter) {
     225  80
             final String txt = (text == null) ? "" : text;
     226  80
             final StringBuilder sb = new StringBuilder(txt.length() + (20 * ec.size()));
     227  80
             sb.append(' ').append(txt).append(' ');
     228  80
             for (Evidence e : ec.iterator(confidenceFilter)) {
     229  328
                 String value = e.getValue();
     230  
     
     231  
                 //hack to get around the fact that lucene does a really good job of recognizing domains and not
     232  
                 // splitting them. TODO - put together a better lucene analyzer specific to the domain.
     233  328
                 if (value.startsWith("http://")) {
     234  16
                     value = value.substring(7).replaceAll("\\.", " ");
     235  
                 }
     236  328
                 if (value.startsWith("https://")) {
     237  0
                     value = value.substring(8).replaceAll("\\.", " ");
     238  
                 }
     239  328
                 if (sb.indexOf(" " + value + " ") < 0) {
     240  296
                     sb.append(value).append(' ');
     241  
                 }
     242  328
             }
     243  80
             return sb.toString().trim();
     244  
         }
     245  
     
     246  
         /**
     247  
          * <p>
     248  
          * Searches the Lucene CPE index to identify possible CPE entries associated with the supplied vendor, product, and
     249  
          * version.</p>
     250  
          *
     251  
          * <p>
     252  
          * If either the vendorWeightings or productWeightings lists have been populated this data is used to add weighting factors to
     253  
          * the search.</p>
     254  
          *
     255  
          * @param vendor the text used to search the vendor field
     256  
          * @param product the text used to search the product field
     257  
          * @param vendorWeightings a list of strings to use to add weighting factors to the vendor field
     258  
          * @param productWeightings Adds a list of strings that will be used to add weighting factors to the product search
     259  
          * @return a list of possible CPE values
     260  
          */
     261  
         protected List<IndexEntry> searchCPE(String vendor, String product,
     262  
                 Set<String> vendorWeightings, Set<String> productWeightings) {
     263  
     
     264  6
             final String searchString = buildSearch(vendor, product, vendorWeightings, productWeightings);
     265  6
             if (searchString == null) {
     266  0
                 return ret;
     267  
     264  48
             final List<IndexEntry> ret = new ArrayList<IndexEntry>(MAX_QUERY_RESULTS);
     265  
     
     266  48
             final String searchString = buildSearch(vendor, product, vendorWeightings, productWeightings);
     267  48
             if (searchString == null) {
     268  0
                 return ret;
     269  
             }
     268  
     270  
             try {
     269  6
                 final TopDocs docs = cpe.search(searchString, MAX_QUERY_RESULTS);
     270  156
                 for (ScoreDoc d : docs.scoreDocs) {
     271  150
                     if (d.score >= 0.08) {
     272  47
                         final Document doc = cpe.getDocument(d.doc);
     273  47
                         final IndexEntry entry = new IndexEntry();
     274  47
                         entry.setVendor(doc.get(Fields.VENDOR));
     275  47
                         entry.setProduct(doc.get(Fields.PRODUCT));
     276  47
                         entry.setSearchScore(d.score);
     277  47
                         if (!ret.contains(entry)) {
     278  47
                             ret.add(entry);
     279  
                         }
     280  
                     }
     271  48
                 final TopDocs docs = cpe.search(searchString, MAX_QUERY_RESULTS);
     272  1248
                 for (ScoreDoc d : docs.scoreDocs) {
     273  1200
                     if (d.score >= 0.08) {
     274  344
                         final Document doc = cpe.getDocument(d.doc);
     275  344
                         final IndexEntry entry = new IndexEntry();
     276  344
                         entry.setVendor(doc.get(Fields.VENDOR));
     277  344
                         entry.setProduct(doc.get(Fields.PRODUCT));
     278  344
                         entry.setSearchScore(d.score);
     279  344
                         if (!ret.contains(entry)) {
     280  344
                             ret.add(entry);
     281  
                         }
     282  
                     }
     283  
                 }
     282  6
                 return ret;
     283  0
             } catch (ParseException ex) {
     284  0
                 final String msg = String.format("Unable to parse: %s", searchString);
     285  0
                 LOGGER.log(Level.WARNING, "An error occured querying the CPE data. See the log for more details.");
     286  0
                 LOGGER.log(Level.INFO, msg, ex);
     287  0
             } catch (IOException ex) {
     288  0
                 final String msg = String.format("IO Error with search string: %s", searchString);
     289  0
                 LOGGER.log(Level.WARNING, "An error occured reading CPE data. See the log for more details.");
     290  0
                 LOGGER.log(Level.INFO, msg, ex);
     284  48
                 return ret;
     285  0
             } catch (ParseException ex) {
     286  0
                 LOGGER.warn("An error occured querying the CPE data. See the log for more details.");
     287  0
                 LOGGER.info("Unable to parse: {}", searchString, ex);
     288  0
             } catch (IOException ex) {
     289  0
                 LOGGER.warn("An error occured reading CPE data. See the log for more details.");
     290  0
                 LOGGER.info("IO Error with search string: {}", searchString, ex);
     291  0
             }
     292  0
             return null;
     293  
         protected String buildSearch(String vendor, String product,
     310  
                 Set<String> vendorWeighting, Set<String> productWeightings) {
     311  6
             final String v = vendor; //.replaceAll("[^\\w\\d]", " ");
     312  6
             final String p = product; //.replaceAll("[^\\w\\d]", " ");
     313  6
             final StringBuilder sb = new StringBuilder(v.length() + p.length()
     311  48
             final String v = vendor; //.replaceAll("[^\\w\\d]", " ");
     312  48
             final String p = product; //.replaceAll("[^\\w\\d]", " ");
     313  48
             final StringBuilder sb = new StringBuilder(v.length() + p.length()
     314  
                     + Fields.PRODUCT.length() + Fields.VENDOR.length() + STRING_BUILDER_BUFFER);
     315  
     
     316  6
             if (!appendWeightedSearch(sb, Fields.PRODUCT, p, productWeightings)) {
     316  48
             if (!appendWeightedSearch(sb, Fields.PRODUCT, p, productWeightings)) {
     317  0
                 return null;
     318  
             }
     319  6
             sb.append(" AND ");
     320  6
             if (!appendWeightedSearch(sb, Fields.VENDOR, v, vendorWeighting)) {
     319  48
             sb.append(" AND ");
     320  48
             if (!appendWeightedSearch(sb, Fields.VENDOR, v, vendorWeighting)) {
     321  0
                 return null;
     322  
             }
     323  6
             return sb.toString();
     323  48
             return sb.toString();
     324  
         }
     325  
          */
     336  
         private boolean appendWeightedSearch(StringBuilder sb, String field, String searchText, Set<String> weightedText) {
     337  12
             sb.append(" ").append(field).append(":( ");
     337  96
             sb.append(" ").append(field).append(":( ");
     338  
     
     339  12
             final String cleanText = cleanseText(searchText);
     339  96
             final String cleanText = cleanseText(searchText);
     340  
     
     341  12
             if ("".equals(cleanText)) {
     341  96
             if ("".equals(cleanText)) {
     342  0
                 return false;
     343  
             }
     344  
     
     345  12
             if (weightedText == null || weightedText.isEmpty()) {
     345  96
             if (weightedText == null || weightedText.isEmpty()) {
     346  0
                 LuceneUtils.appendEscapedLuceneQuery(sb, cleanText);
     347  
             } else {
     348  12
                 final StringTokenizer tokens = new StringTokenizer(cleanText);
     349  159
                 while (tokens.hasMoreElements()) {
     350  147
                     final String word = tokens.nextToken();
     351  147
                     String temp = null;
     352  147
                     for (String weighted : weightedText) {
     353  341
                         final String weightedStr = cleanseText(weighted);
     354  341
                         if (equalsIgnoreCaseAndNonAlpha(word, weightedStr)) {
     355  22
                             temp = LuceneUtils.escapeLuceneQuery(word) + WEIGHTING_BOOST;
     356  22
                             if (!word.equalsIgnoreCase(weightedStr)) {
     348  96
                 final StringTokenizer tokens = new StringTokenizer(cleanText);
     349  1232
                 while (tokens.hasMoreElements()) {
     350  1136
                     final String word = tokens.nextToken();
     351  1136
                     String temp = null;
     352  1136
                     for (String weighted : weightedText) {
     353  2640
                         final String weightedStr = cleanseText(weighted);
     354  2640
                         if (equalsIgnoreCaseAndNonAlpha(word, weightedStr)) {
     355  176
                             temp = LuceneUtils.escapeLuceneQuery(word) + WEIGHTING_BOOST;
     356  176
                             if (!word.equalsIgnoreCase(weightedStr)) {
     357  0
                                 temp += " " + LuceneUtils.escapeLuceneQuery(weightedStr) + WEIGHTING_BOOST;
     358  
                             }
     359  
                         }
     360  341
                     }
     361  147
                     if (temp == null) {
     362  125
                         temp = LuceneUtils.escapeLuceneQuery(word);
     360  2640
                     }
     361  1136
                     if (temp == null) {
     362  960
                         temp = LuceneUtils.escapeLuceneQuery(word);
     363  
                     }
     364  147
                     sb.append(" ").append(temp);
     365  147
                 }
     364  1136
                     sb.append(" ").append(temp);
     365  1136
                 }
     366  
             }
     367  12
             sb.append(" ) ");
     368  12
             return true;
     367  96
             sb.append(" ) ");
     368  96
             return true;
     369  
         }
     370  
          */
     377  
         private String cleanseText(String text) {
     378  353
             return text.replaceAll(CLEANSE_CHARACTER_RX, " ");
     378  2736
             return text.replaceAll(CLEANSE_CHARACTER_RX, " ");
     379  
         }
     380  
          */
     388  
         private boolean equalsIgnoreCaseAndNonAlpha(String l, String r) {
     389  341
             if (l == null || r == null) {
     389  2640
             if (l == null || r == null) {
     390  0
                 return false;
     391  
             }
     392  
     
     393  341
             final String left = l.replaceAll(CLEANSE_NONALPHA_RX, "");
     394  341
             final String right = r.replaceAll(CLEANSE_NONALPHA_RX, "");
     395  341
             return left.equalsIgnoreCase(right);
     393  2640
             final String left = l.replaceAll(CLEANSE_NONALPHA_RX, "");
     394  2640
             final String right = r.replaceAll(CLEANSE_NONALPHA_RX, "");
     395  2640
             return left.equalsIgnoreCase(right);
     396  
         }
     397  
          */
     406  
         private boolean verifyEntry(final IndexEntry entry, final Dependency dependency) {
     407  47
             boolean isValid = false;
     407  344
             boolean isValid = false;
     408  
     
     409  47
             if (collectionContainsString(dependency.getProductEvidence(), entry.getProduct())
     409  
             //TODO - does this nullify some of the fuzzy matching that happens in the lucene search?
     410  
             // for instance CPE some-component and in the evidence we have SomeComponent.
     411  344
             if (collectionContainsString(dependency.getProductEvidence(), entry.getProduct())
     412  
                     && collectionContainsString(dependency.getVendorEvidence(), entry.getVendor())) {
     411  
                 //&& collectionContainsVersion(dependency.getVersionEvidence(), entry.getVersion())
     412  2
                 isValid = true;
     413  
             }
     414  47
             return isValid;
                 //&& collectionContainsVersion(dependency.getVersionEvidence(), entry.getVersion())
     414  24
                 isValid = true;
     415  
         }
     416  
     
             }
     416  344
             return isValid;
     417  
         /**
         }
     418  
          * Used to determine if the EvidenceCollection contains a specific string.
     
     419  
          *
         /**
     420  
          * @param ec an EvidenceCollection
          * Used to determine if the EvidenceCollection contains a specific string.
     421  
          * @param text the text to search for
          *
     422  
          * @return whether or not the EvidenceCollection contains the string
          * @param ec an EvidenceCollection
     423  
          */
          * @param text the text to search for
     424  
         private boolean collectionContainsString(EvidenceCollection ec, String text) {
          * @return whether or not the EvidenceCollection contains the string
     425  
          */
     426  
         private boolean collectionContainsString(EvidenceCollection ec, String text) {
     427  
             //TODO - likely need to change the split... not sure if this will work for CPE with special chars
     426  49
             if (text == null) {
     427  0
                 return false;
     428  
     428  376
             if (text == null) {
     429  0
                 return false;
     430  
             }
     429  49
             final String[] words = text.split("[\\s_-]");
     430  49
             final List<String> list = new ArrayList<String>();
     431  49
             String tempWord = null;
     432  187
             for (String word : words) {
     433  
                 /*
     434  
                  single letter words should be concatenated with the next word.
     431  376
             final String[] words = text.split("[\\s_-]");
     432  376
             final List<String> list = new ArrayList<String>();
     433  376
             String tempWord = null;
     434  1360
             for (String word : words) {
     435  
                  so { "m", "core", "sample" } -> { "mcore", "sample" }
                 /*
     436  
                  single letter words should be concatenated with the next word.
     437  
                  so { "m", "core", "sample" } -> { "mcore", "sample" }
     438  
                  */
     437  138
                 if (tempWord != null) {
     438  6
                     list.add(tempWord + word);
     439  6
                     tempWord = null;
     440  132
                 } else if (word.length() <= 2) {
     441  6
                     tempWord = word;
     442  
                 } else {
     443  126
                     list.add(word);
     439  984
                 if (tempWord != null) {
     440  40
                     list.add(tempWord + word);
     441  40
                     tempWord = null;
     442  944
                 } else if (word.length() <= 2) {
     443  40
                     tempWord = word;
     444  
                 } else {
     445  904
                     list.add(word);
     446  
                 }
     445  
     447  
             }
     446  49
             if (tempWord != null) {
     447  0
                 if (!list.isEmpty()) {
     448  0
                     final String tmp = list.get(list.size() - 1) + tempWord;
     449  0
                     list.add(tmp);
     450  0
                 } else {
     451  0
                     list.add(tempWord);
     452  
     448  376
             if (tempWord != null) {
     449  0
                 if (!list.isEmpty()) {
     450  0
                     final String tmp = list.get(list.size() - 1) + tempWord;
     451  0
                     list.add(tmp);
     452  0
                 } else {
     453  0
                     list.add(tempWord);
     454  
                 }
     453  
     455  
             }
     454  49
             if (list.isEmpty()) {
     455  0
                 return false;
     456  
     456  376
             if (list.isEmpty()) {
     457  0
                 return false;
     458  
             }
     457  49
             boolean contains = true;
     458  49
             for (String word : list) {
     459  132
                 contains &= ec.containsUsedString(word);
     460  132
             }
     461  49
             return contains;
     462  
         }
     463  
     
     459  376
             boolean contains = true;
     460  376
             for (String word : list) {
     461  944
                 contains &= ec.containsUsedString(word);
     462  944
             }
     463  376
             return contains;
     464  
         /**
         }
     465  
          * Analyzes a dependency and attempts to determine if there are any CPE identifiers for this dependency.
     
     466  
          *
         /**
     467  
          * @param dependency The Dependency to analyze.
          * Analyzes a dependency and attempts to determine if there are any CPE identifiers for this dependency.
     468  
          * @param engine The analysis engine
     469  
          * @throws AnalysisException is thrown if there is an issue analyzing the dependency.
     470  
          */
     471  
         @Override
     472  
         public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
     473  
             try {
     474  2
                 determineCPE(dependency);
     475  0
             } catch (CorruptIndexException ex) {
     476  0
                 throw new AnalysisException("CPE Index is corrupt.", ex);
     477  0
             } catch (IOException ex) {
     478  0
                 throw new AnalysisException("Failure opening the CPE Index.", ex);
     479  0
             } catch (ParseException ex) {
     480  0
                 throw new AnalysisException("Unable to parse the generated Lucene query for this dependency.", ex);
     481  2
             }
     482  2
         }
     483  
     
     484  
         /**
     485  
          * Retrieves a list of CPE values from the CveDB based on the vendor and product passed in. The list is then validated to find
     486  
          * only CPEs that are valid for the given dependency. It is possible that the CPE identified is a best effort "guess" based on
     487  
          * the vendor, product, and version information.
     488  
          *
     469  
          * @param dependency The Dependency to analyze.
     470  
          * @param engine The analysis engine
     471  
          * @throws AnalysisException is thrown if there is an issue analyzing the dependency.
     472  
          */
     473  
         @Override
     474  
         public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
     475  
             try {
     476  16
                 determineCPE(dependency);
     477  0
             } catch (CorruptIndexException ex) {
     478  0
                 throw new AnalysisException("CPE Index is corrupt.", ex);
     479  0
             } catch (IOException ex) {
     480  0
                 throw new AnalysisException("Failure opening the CPE Index.", ex);
     481  0
             } catch (ParseException ex) {
     482  0
                 throw new AnalysisException("Unable to parse the generated Lucene query for this dependency.", ex);
     483  16
             }
     484  16
         }
     485  
     
     486  
         /**
     487  
          * Retrieves a list of CPE values from the CveDB based on the vendor and product passed in. The list is then validated to find
     488  
          * only CPEs that are valid for the given dependency. It is possible that the CPE identified is a best effort "guess" based on
     489  
          * @param dependency the Dependency being analyzed
          * the vendor, product, and version information.
     490  
          * @param vendor the vendor for the CPE being analyzed
          *
     491  
          * @param product the product for the CPE being analyzed
          * @param dependency the Dependency being analyzed
     492  
          * @param currentConfidence the current confidence being used during analysis
          * @param vendor the vendor for the CPE being analyzed
     493  
          * @return <code>true</code> if an identifier was added to the dependency; otherwise <code>false</code>
          * @param product the product for the CPE being analyzed
     494  
          * @throws UnsupportedEncodingException is thrown if UTF-8 is not supported
          * @param currentConfidence the current confidence being used during analysis
     495  
          */
          * @return <code>true</code> if an identifier was added to the dependency; otherwise <code>false</code>
     496  
         protected boolean determineIdentifiers(Dependency dependency, String vendor, String product,
          * @throws UnsupportedEncodingException is thrown if UTF-8 is not supported
     497  
          */
     498  
         protected boolean determineIdentifiers(Dependency dependency, String vendor, String product,
     499  
                 Confidence currentConfidence) throws UnsupportedEncodingException {
     498  2
             final Set<VulnerableSoftware> cpes = cve.getCPEs(vendor, product);
     499  2
             DependencyVersion bestGuess = new DependencyVersion("-");
     500  2
             Confidence bestGuessConf = null;
     501  2
             boolean hasBroadMatch = false;
     502  2
             final List<IdentifierMatch> collected = new ArrayList<IdentifierMatch>();
     503  10
             for (Confidence conf : Confidence.values()) {
     504  
     //            if (conf.compareTo(currentConfidence) > 0) {
     505  
     //                break;
     500  24
             final Set<VulnerableSoftware> cpes = cve.getCPEs(vendor, product);
     501  24
             DependencyVersion bestGuess = new DependencyVersion("-");
     502  24
             Confidence bestGuessConf = null;
     503  24
             boolean hasBroadMatch = false;
     504  24
             final List<IdentifierMatch> collected = new ArrayList<IdentifierMatch>();
     505  120
             for (Confidence conf : Confidence.values()) {
     506  
     //            if (conf.compareTo(currentConfidence) > 0) {
     507  
     //                break;
     508  
     //            }
     507  8
                 for (Evidence evidence : dependency.getVersionEvidence().iterator(conf)) {
     508  8
                     final DependencyVersion evVer = DependencyVersionUtil.parseVersion(evidence.getValue());
     509  8
                     if (evVer == null) {
     510  0
                         continue;
     511  
                     }
     512  8
                     for (VulnerableSoftware vs : cpes) {
     509  96
                 for (Evidence evidence : dependency.getVersionEvidence().iterator(conf)) {
     510  96
                     final DependencyVersion evVer = DependencyVersionUtil.parseVersion(evidence.getValue());
     511  96
                     if (evVer == null) {
     512  0
                         continue;
     513  
                     }
     514  96
                     for (VulnerableSoftware vs : cpes) {
     515  
                         DependencyVersion dbVer;
     514  312
                         if (vs.getRevision() != null && !vs.getRevision().isEmpty()) {
     515  128
                             dbVer = DependencyVersionUtil.parseVersion(vs.getVersion() + "." + vs.getRevision());
     516  
                         } else {
     517  184
                             dbVer = DependencyVersionUtil.parseVersion(vs.getVersion());
     516  3488
                         if (vs.getUpdate() != null && !vs.getUpdate().isEmpty()) {
     517  1024
                             dbVer = DependencyVersionUtil.parseVersion(vs.getVersion() + "." + vs.getUpdate());
     518  
                         } else {
     519  2464
                             dbVer = DependencyVersionUtil.parseVersion(vs.getVersion());
     520  
                         }
     519  312
                         if (dbVer == null) { //special case, no version specified - everything is vulnerable
     520  0
                             hasBroadMatch = true;
     521  0
                             final String url = String.format(NVD_SEARCH_URL, URLEncoder.encode(vs.getName(), "UTF-8"));
     522  0
                             final IdentifierMatch match = new IdentifierMatch("cpe", vs.getName(), url, IdentifierConfidence.BROAD_MATCH, conf);
     523  0
                             collected.add(match);
     524  0
                         } else if (evVer.equals(dbVer)) { //yeah! exact match
     525  8
                             final String url = String.format(NVD_SEARCH_URL, URLEncoder.encode(vs.getName(), "UTF-8"));
     526  8
                             final IdentifierMatch match = new IdentifierMatch("cpe", vs.getName(), url, IdentifierConfidence.EXACT_MATCH, conf);
     527  8
                             collected.add(match);
     528  8
                         } else {
     529  
                             //TODO the following isn't quite right is it? need to think about this guessing game a bit more.
     530  304
                             if (evVer.getVersionParts().size() <= dbVer.getVersionParts().size()
     521  3488
                         if (dbVer == null) { //special case, no version specified - everything is vulnerable
     522  0
                             hasBroadMatch = true;
     523  0
                             final String url = String.format(NVD_SEARCH_URL, URLEncoder.encode(vs.getName(), "UTF-8"));
     524  0
                             final IdentifierMatch match = new IdentifierMatch("cpe", vs.getName(), url, IdentifierConfidence.BROAD_MATCH, conf);
     525  0
                             collected.add(match);
     526  0
                         } else if (evVer.equals(dbVer)) { //yeah! exact match
     527  64
                             final String url = String.format(NVD_SEARCH_URL, URLEncoder.encode(vs.getName(), "UTF-8"));
     528  64
                             final IdentifierMatch match = new IdentifierMatch("cpe", vs.getName(), url, IdentifierConfidence.EXACT_MATCH, conf);
     529  64
                             collected.add(match);
     530  64
                         } else {
     531  
                             //TODO the following isn't quite right is it? need to think about this guessing game a bit more.
     532  3424
                             if (evVer.getVersionParts().size() <= dbVer.getVersionParts().size()
     533  
                                     && evVer.matchesAtLeastThreeLevels(dbVer)) {
     532  64
                                 if (bestGuessConf == null || bestGuessConf.compareTo(conf) > 0) {
     533  2
                                     if (bestGuess.getVersionParts().size() < dbVer.getVersionParts().size()) {
     534  2
                                         bestGuess = dbVer;
     535  2
                                         bestGuessConf = conf;
     536  
                                     }
     537  
                                 }
     534  512
                                 if (bestGuessConf == null || bestGuessConf.compareTo(conf) > 0) {
     535  16
                                     if (bestGuess.getVersionParts().size() < dbVer.getVersionParts().size()) {
     536  16
                                         bestGuess = dbVer;
     537  16
                                         bestGuessConf = conf;
     538  
                             }
                                     }
     539  
                                 }
     540  
                             }
     541  
                         }
     540  312
                     }
     541  8
                     if (bestGuessConf == null || bestGuessConf.compareTo(conf) > 0) {
     542  0
                         if (bestGuess.getVersionParts().size() < evVer.getVersionParts().size()) {
     543  0
                             bestGuess = evVer;
     544  0
                             bestGuessConf = conf;
     545  
     542  3488
                     }
     543  96
                     if (bestGuessConf == null || bestGuessConf.compareTo(conf) > 0) {
     544  8
                         if (bestGuess.getVersionParts().size() < evVer.getVersionParts().size()) {
     545  8
                             bestGuess = evVer;
     546  8
                             bestGuessConf = conf;
     547  
                         }
     546  
                     }
     547  8
                 }
     548  
                     }
     549  96
                 }
     550  
             }
     549  2
             final String cpeName = String.format("cpe:/a:%s:%s:%s", vendor, product, bestGuess.toString());
     550  2
             String url = null;
     551  2
             if (hasBroadMatch) { //if we have a broad match we can add the URL to the best guess.
     552  0
                 final String cpeUrlName = String.format("cpe:/a:%s:%s", vendor, product);
     553  0
                 url = String.format(NVD_SEARCH_URL, URLEncoder.encode(cpeUrlName, "UTF-8"));
     554  
     551  24
             final String cpeName = String.format("cpe:/a:%s:%s:%s", vendor, product, bestGuess.toString());
     552  24
             String url = null;
     553  24
             if (hasBroadMatch) { //if we have a broad match we can add the URL to the best guess.
     554  0
                 final String cpeUrlName = String.format("cpe:/a:%s:%s", vendor, product);
     555  0
                 url = String.format(NVD_SEARCH_URL, URLEncoder.encode(cpeUrlName, "UTF-8"));
     556  
             }
     555  2
             if (bestGuessConf == null) {
     556  0
                 bestGuessConf = Confidence.LOW;
     557  
     557  24
             if (bestGuessConf == null) {
     558  0
                 bestGuessConf = Confidence.LOW;
     559  
             }
     558  2
             final IdentifierMatch match = new IdentifierMatch("cpe", cpeName, url, IdentifierConfidence.BEST_GUESS, bestGuessConf);
     559  2
             collected.add(match);
     560  
     560  24
             final IdentifierMatch match = new IdentifierMatch("cpe", cpeName, url, IdentifierConfidence.BEST_GUESS, bestGuessConf);
     561  24
             collected.add(match);
     562  
     
     561  2
             Collections.sort(collected);
     562  2
             final IdentifierConfidence bestIdentifierQuality = collected.get(0).getConfidence();
     563  2
             final Confidence bestEvidenceQuality = collected.get(0).getEvidenceConfidence();
     564  2
             boolean identifierAdded = false;
     565  2
             for (IdentifierMatch m : collected) {
     566  10
                 if (bestIdentifierQuality.equals(m.getConfidence())
     567  
     563  24
             Collections.sort(collected);
     564  24
             final IdentifierConfidence bestIdentifierQuality = collected.get(0).getConfidence();
     565  24
             final Confidence bestEvidenceQuality = collected.get(0).getEvidenceConfidence();
     566  24
             boolean identifierAdded = false;
     567  24
             for (IdentifierMatch m : collected) {
     568  88
                 if (bestIdentifierQuality.equals(m.getConfidence())
     569  
                         && bestEvidenceQuality.equals(m.getEvidenceConfidence())) {
     568  2
                     final Identifier i = m.getIdentifier();
     569  2
                     if (bestIdentifierQuality == IdentifierConfidence.BEST_GUESS) {
     570  0
                         i.setConfidence(Confidence.LOW);
     571  
                     } else {
     572  2
                         i.setConfidence(bestEvidenceQuality);
     570  24
                     final Identifier i = m.getIdentifier();
     571  24
                     if (bestIdentifierQuality == IdentifierConfidence.BEST_GUESS) {
     572  8
                         i.setConfidence(Confidence.LOW);
     573  
                     } else {
     574  16
                         i.setConfidence(bestEvidenceQuality);
     575  
                     }
     574  2
                     dependency.addIdentifier(i);
     575  2
                     identifierAdded = true;
     576  
     576  24
                     dependency.addIdentifier(i);
     577  24
                     identifierAdded = true;
     578  
                 }
     577  10
             }
     578  2
             return identifierAdded;
     579  
         }
     580  
     
     579  88
             }
     580  24
             return identifierAdded;
     581  
         /**
         }
     582  
          * The confidence whether the identifier is an exact match, or a best guess.
     
     583  
          */
     584  4
         private enum IdentifierConfidence {
     585  
     
     586  
             /**
     587  
              * An exact match for the CPE.
     588  
              */
     589  1
             EXACT_MATCH,
     590  
             /**
     591  
              * A best guess for the CPE.
     592  
              */
     593  1
             BEST_GUESS,
     594  
             /**
     595  
              * The entire vendor/product group must be added (without a guess at version) because there is a CVE with a VS that only
     596  
              * specifies vendor/product.
     597  
              */
     598  1
             BROAD_MATCH
     599  
         }
     600  
     
     601  
         /**
     602  
          * A simple object to hold an identifier and carry information about the confidence in the identifier.
     603  
     584  
          * The confidence whether the identifier is an exact match, or a best guess.
     585  
          */
     604  8
         private static class IdentifierMatch implements Comparable<IdentifierMatch> {
     605  
     586  32
         private enum IdentifierConfidence {
     587  
     
     606  
     588  
             /**
     607  
              * Constructs an IdentifierMatch.
     608  
              *
     609  
              * @param type the type of identifier (such as CPE)
     610  
              * @param value the value of the identifier
     611  
              * @param url the URL of the identifier
     612  
              * @param identifierConfidence the confidence in the identifier: best guess or exact match
     613  
              * @param evidenceConfidence the confidence of the evidence used to find the identifier
     614  
     589  
              * An exact match for the CPE.
     590  
              */
     615  10
             IdentifierMatch(String type, String value, String url, IdentifierConfidence identifierConfidence, Confidence evidenceConfidence) {
     616  10
                 this.identifier = new Identifier(type, value, url);
     617  10
                 this.confidence = identifierConfidence;
     618  10
                 this.evidenceConfidence = evidenceConfidence;
     619  10
             }
     620  
             //<editor-fold defaultstate="collapsed" desc="Property implementations: evidenceConfidence, confidence, identifier">
     621  
     591  8
             EXACT_MATCH,
     592  
             /**
     622  
              * The confidence in the evidence used to identify this match.
     623  
     593  
              * A best guess for the CPE.
     594  
              */
     624  
             private Confidence evidenceConfidence;
     625  
     
     626  
     595  8
             BEST_GUESS,
     596  
             /**
     627  
              * Get the value of evidenceConfidence
     628  
              *
     629  
              * @return the value of evidenceConfidence
     630  
     597  
              * The entire vendor/product group must be added (without a guess at version) because there is a CVE with a VS that only
     598  
              * specifies vendor/product.
     599  
              */
     631  
             public Confidence getEvidenceConfidence() {
     632  10
                 return evidenceConfidence;
     633  
             }
     634  
     
     635  
             /**
     636  
              * Set the value of evidenceConfidence
     637  
              *
     638  
              * @param evidenceConfidence new value of evidenceConfidence
     639  
              */
     640  
             public void setEvidenceConfidence(Confidence evidenceConfidence) {
     641  0
                 this.evidenceConfidence = evidenceConfidence;
     642  0
             }
     643  
             /**
     644  
              * The confidence whether this is an exact match, or a best guess.
     645  
              */
     646  
             private IdentifierConfidence confidence;
     647  
     
     648  
             /**
     649  
              * Get the value of confidence.
     650  
              *
     651  
              * @return the value of confidence
     652  
              */
     653  
             public IdentifierConfidence getConfidence() {
     654  12
                 return confidence;
     655  
             }
     656  
     
     657  
             /**
     658  
              * Set the value of confidence.
     659  
              *
     660  
              * @param confidence new value of confidence
     661  
              */
     662  
             public void setConfidence(IdentifierConfidence confidence) {
     663  0
                 this.confidence = confidence;
     664  0
             }
     665  
             /**
     666  
              * The CPE identifier.
     667  
              */
     668  
             private Identifier identifier;
     669  
     
     670  
             /**
     671  
              * Get the value of identifier.
     672  
              *
     673  
              * @return the value of identifier
     674  
              */
     675  
             public Identifier getIdentifier() {
     676  2
                 return identifier;
     677  
             }
     678  
     
     679  
             /**
     680  
              * Set the value of identifier.
     681  
              *
     682  
              * @param identifier new value of identifier
     683  
              */
     684  
             public void setIdentifier(Identifier identifier) {
     685  0
                 this.identifier = identifier;
     686  0
             }
     687  
             //</editor-fold>
     688  
             //<editor-fold defaultstate="collapsed" desc="Standard implementations of toString, hashCode, and equals">
     689  
     
     690  
             /**
     691  
              * Standard toString() implementation.
     692  
              *
     693  
              * @return the string representation of the object
     694  
              */
     695  
             @Override
     696  
             public String toString() {
     697  0
                 return "IdentifierMatch{" + "evidenceConfidence=" + evidenceConfidence
     698  
                         + ", confidence=" + confidence + ", identifier=" + identifier + '}';
     699  
             }
     700  
     
     701  
             /**
     702  
              * Standard hashCode() implementation.
     703  
              *
     704  
              * @return the hashCode
     705  
              */
     706  
             @Override
     707  
             public int hashCode() {
     708  0
                 int hash = 5;
     709  0
                 hash = 97 * hash + (this.evidenceConfidence != null ? this.evidenceConfidence.hashCode() : 0);
     710  0
                 hash = 97 * hash + (this.confidence != null ? this.confidence.hashCode() : 0);
     711  0
                 hash = 97 * hash + (this.identifier != null ? this.identifier.hashCode() : 0);
     712  0
                 return hash;
     713  
             }
     714  
     
     715  
             /**
     716  
              * Standard equals implementation.
     717  
              *
     718  
              * @param obj the object to compare
     719  
              * @return true if the objects are equal, otherwise false
     720  
              */
     721  
             @Override
     722  
             public boolean equals(Object obj) {
     723  0
                 if (obj == null) {
     724  0
                     return false;
     725  
                 }
     726  0
                 if (getClass() != obj.getClass()) {
     727  0
                     return false;
     728  
                 }
     729  0
                 final IdentifierMatch other = (IdentifierMatch) obj;
     730  0
                 if (this.evidenceConfidence != other.evidenceConfidence) {
     731  0
                     return false;
     732  
                 }
     733  0
                 if (this.confidence != other.confidence) {
     734  0
                     return false;
     735  
                 }
     736  0
                 if (this.identifier != other.identifier && (this.identifier == null || !this.identifier.equals(other.identifier))) {
     737  0
                     return false;
     738  
                 }
     739  0
                 return true;
     740  
             }
     741  
             //</editor-fold>
     742  
     
     743  
             /**
     744  
              * Standard implementation of compareTo that compares identifier confidence, evidence confidence, and then the identifier.
     745  
              *
     746  
              * @param o the IdentifierMatch to compare to
     747  
              * @return the natural ordering of IdentifierMatch
     748  
              */
     749  
             @Override
     750  
             public int compareTo(IdentifierMatch o) {
     751  8
                 int conf = this.confidence.compareTo(o.confidence);
     752  8
                 if (conf == 0) {
     753  6
                     conf = this.evidenceConfidence.compareTo(o.evidenceConfidence);
     754  6
                     if (conf == 0) {
     755  2
                         conf = identifier.compareTo(o.identifier);
     756  
                     }
     757  
                 }
     758  8
                 return conf;
     759  
             }
     760  
     600  8
             BROAD_MATCH
     601  
         }
     602  
     
     603  
         /**
     604  
          * A simple object to hold an identifier and carry information about the confidence in the identifier.
     605  
          */
     606  64
         private static class IdentifierMatch implements Comparable<IdentifierMatch> {
     607  
     
     608  
             /**
     609  
              * Constructs an IdentifierMatch.
     610  
              *
     611  
              * @param type the type of identifier (such as CPE)
     612  
              * @param value the value of the identifier
     613  
              * @param url the URL of the identifier
     614  
              * @param identifierConfidence the confidence in the identifier: best guess or exact match
     615  
              * @param evidenceConfidence the confidence of the evidence used to find the identifier
     616  
              */
     617  88
             IdentifierMatch(String type, String value, String url, IdentifierConfidence identifierConfidence, Confidence evidenceConfidence) {
     618  88
                 this.identifier = new Identifier(type, value, url);
     619  88
                 this.confidence = identifierConfidence;
     620  88
                 this.evidenceConfidence = evidenceConfidence;
     621  88
             }
     622  
             //<editor-fold defaultstate="collapsed" desc="Property implementations: evidenceConfidence, confidence, identifier">
     623  
             /**
     624  
              * The confidence in the evidence used to identify this match.
     625  
              */
     626  
             private Confidence evidenceConfidence;
     627  
     
     628  
             /**
     629  
              * Get the value of evidenceConfidence
     630  
              *
     631  
              * @return the value of evidenceConfidence
     632  
              */
     633  
             public Confidence getEvidenceConfidence() {
     634  96
                 return evidenceConfidence;
     635  
             }
     636  
     
     637  
             /**
     638  
              * Set the value of evidenceConfidence
     639  
              *
     640  
              * @param evidenceConfidence new value of evidenceConfidence
     641  
              */
     642  
             public void setEvidenceConfidence(Confidence evidenceConfidence) {
     643  0
                 this.evidenceConfidence = evidenceConfidence;
     644  0
             }
     645  
             /**
     646  
              * The confidence whether this is an exact match, or a best guess.
     647  
              */
     648  
             private IdentifierConfidence confidence;
     649  
     
     650  
             /**
     651  
              * Get the value of confidence.
     652  
              *
     653  
              * @return the value of confidence
     654  
              */
     655  
             public IdentifierConfidence getConfidence() {
     656  112
                 return confidence;
     657  
             }
     658  
     
     659  
             /**
     660  
              * Set the value of confidence.
     661  
              *
     662  
              * @param confidence new value of confidence
     663  
              */
     664  
             public void setConfidence(IdentifierConfidence confidence) {
     665  0
                 this.confidence = confidence;
     666  0
             }
     667  
             /**
     668  
              * The CPE identifier.
     669  
              */
     670  
             private Identifier identifier;
     671  
     
     672  
             /**
     673  
              * Get the value of identifier.
     674  
              *
     675  
              * @return the value of identifier
     676  
              */
     677  
             public Identifier getIdentifier() {
     678  24
                 return identifier;
     679  
             }
     680  
     
     681  
             /**
     682  
              * Set the value of identifier.
     683  
              *
     684  
              * @param identifier new value of identifier
     685  
              */
     686  
             public void setIdentifier(Identifier identifier) {
     687  0
                 this.identifier = identifier;
     688  0
             }
     689  
             //</editor-fold>
     690  
             //<editor-fold defaultstate="collapsed" desc="Standard implementations of toString, hashCode, and equals">
     691  
     
     692  
             /**
     693  
              * Standard toString() implementation.
     694  
              *
     695  
              * @return the string representation of the object
     696  
              */
     697  
             @Override
     698  
             public String toString() {
     699  0
                 return "IdentifierMatch{" + "evidenceConfidence=" + evidenceConfidence
     700  
                         + ", confidence=" + confidence + ", identifier=" + identifier + '}';
     701  
             }
     702  
     
     703  
             /**
     704  
              * Standard hashCode() implementation.
     705  
              *
     706  
              * @return the hashCode
     707  
              */
     708  
             @Override
     709  
             public int hashCode() {
     710  0
                 int hash = 5;
     711  0
                 hash = 97 * hash + (this.evidenceConfidence != null ? this.evidenceConfidence.hashCode() : 0);
     712  0
                 hash = 97 * hash + (this.confidence != null ? this.confidence.hashCode() : 0);
     713  0
                 hash = 97 * hash + (this.identifier != null ? this.identifier.hashCode() : 0);
     714  0
                 return hash;
     715  
             }
     716  
     
     717  
             /**
     718  
              * Standard equals implementation.
     719  
              *
     720  
              * @param obj the object to compare
     721  
              * @return true if the objects are equal, otherwise false
     722  
              */
     723  
             @Override
     724  
             public boolean equals(Object obj) {
     725  0
                 if (obj == null) {
     726  0
                     return false;
     727  
                 }
     728  0
                 if (getClass() != obj.getClass()) {
     729  0
                     return false;
     730  
                 }
     731  0
                 final IdentifierMatch other = (IdentifierMatch) obj;
     732  0
                 if (this.evidenceConfidence != other.evidenceConfidence) {
     733  0
                     return false;
     734  
                 }
     735  0
                 if (this.confidence != other.confidence) {
     736  0
                     return false;
     737  
                 }
     738  0
                 if (this.identifier != other.identifier && (this.identifier == null || !this.identifier.equals(other.identifier))) {
     739  0
                     return false;
     740  
                 }
     741  0
                 return true;
     742  
             }
     743  
             //</editor-fold>
     744  
     
     745  
             /**
     746  
              * Standard implementation of compareTo that compares identifier confidence, evidence confidence, and then the identifier.
     747  
              *
     748  
              * @param o the IdentifierMatch to compare to
     749  
              * @return the natural ordering of IdentifierMatch
     750  
              */
     751  
             @Override
     752  
             public int compareTo(IdentifierMatch o) {
     753  64
                 int conf = this.confidence.compareTo(o.confidence);
     754  64
                 if (conf == 0) {
     755  48
                     conf = this.evidenceConfidence.compareTo(o.evidenceConfidence);
     756  48
                     if (conf == 0) {
     757  16
                         conf = identifier.compareTo(o.identifier);
     758  
                     }
     759  
                 }
     760  64
                 return conf;
     761  
             }
     762  
         }
     763  
     }
    - + 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 dfb5ba04a..2e0a465ad 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.CentralAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.CentralAnalyzer.html @@ -12,7 +12,7 @@
     
    - +
    Classes in this File Line Coverage Branch Coverage Complexity
    CentralAnalyzer
    25%
    17/68
    13%
    4/30
    3.625
    CentralAnalyzer
    27%
    18/66
    13%
    4/30
    3.625
     
    @@ -56,351 +56,353 @@  19  
     
     20   -
     import java.io.File;
    -  21   -
     import java.io.FileNotFoundException;
    -  22   -
     import java.io.IOException;
    -  23   -
     import java.net.URL;
    -  24   -
     import java.util.List;
    -  25   -
     import java.util.Set;
    -  26   -
     import java.util.logging.Level;
    -  27   -
     import java.util.logging.Logger;
    -  28  
     import org.apache.commons.io.FileUtils;
    -  29   +  21  
     import org.owasp.dependencycheck.Engine;
    -  30   +  22  
     import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
    -  31   +  23  
     import org.owasp.dependencycheck.data.central.CentralSearch;
    -  32   +  24  
     import org.owasp.dependencycheck.data.nexus.MavenArtifact;
    -  33   +  25  
     import org.owasp.dependencycheck.dependency.Confidence;
    -  34   +  26  
     import org.owasp.dependencycheck.dependency.Dependency;
    -  35   +  27  
     import org.owasp.dependencycheck.dependency.Evidence;
    -  36   +  28  
     import org.owasp.dependencycheck.xml.pom.PomUtils;
    +  29   +
     import org.slf4j.Logger;
    +  30   +
     import org.slf4j.LoggerFactory;
    +  31   +
     
    +  32   +
     import java.io.File;
    +  33   +
     import java.io.FileFilter;
    +  34   +
     import java.io.FileNotFoundException;
    +  35   +
     import java.io.IOException;
    +  36   +
     import java.net.URL;
     37   -
     import org.owasp.dependencycheck.utils.DownloadFailedException;
    +
     import java.util.List;
     38   -
     import org.owasp.dependencycheck.utils.Downloader;
    +
     import org.owasp.dependencycheck.utils.DownloadFailedException;
     39   -
     import org.owasp.dependencycheck.utils.InvalidSettingException;
    +
     import org.owasp.dependencycheck.utils.Downloader;
     40   -
     import org.owasp.dependencycheck.utils.Settings;
    +
     import org.owasp.dependencycheck.utils.FileFilterBuilder;
     41   -
     
    +
     import org.owasp.dependencycheck.utils.InvalidSettingException;
     42   -
     /**
    +
     import org.owasp.dependencycheck.utils.Settings;
     43   -
      * Analyzer which will attempt to locate a dependency, and the GAV information, by querying Central for the dependency's SHA-1
    +
     
     44   -
      * digest.
    +
     /**
     45   -
      *
    +
      * Analyzer which will attempt to locate a dependency, and the GAV information, by querying Central for the dependency's SHA-1
     46   -
      * @author colezlaw
    +
      * digest.
     47   -
      */
    -  48  2
     public class CentralAnalyzer extends AbstractFileTypeAnalyzer {
    +
      *
    +  48   +
      * @author colezlaw
     49   -
     
    -  50   -
         /**
    +
      */
    +  50  24
     public class CentralAnalyzer extends AbstractFileTypeAnalyzer {
     51   -
          * The logger.
    +
     
     52   -
          */
    -  53  1
         private static final Logger LOGGER = Logger.getLogger(CentralAnalyzer.class.getName());
    +
         /**
    +  53   +
          * The logger.
     54   -
     
    -  55   -
         /**
    +
          */
    +  55  8
         private static final Logger LOGGER = LoggerFactory.getLogger(CentralAnalyzer.class);
     56   -
          * The name of the analyzer.
    +
     
     57   -
          */
    +
         /**
     58   -
         private static final String ANALYZER_NAME = "Central Analyzer";
    +
          * The name of the analyzer.
     59   -
     
    +
          */
     60   -
         /**
    +
         private static final String ANALYZER_NAME = "Central Analyzer";
     61   -
          * The phase in which this analyzer runs.
    +
     
     62   -
          */
    -  63  1
         private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
    +
         /**
    +  63   +
          * The phase in which this analyzer runs.
     64   -
     
    -  65   -
         /**
    +
          */
    +  65  8
         private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
     66   -
          * The types of files on which this will work.
    +
     
     67   -
          */
    -  68  1
         private static final Set<String> SUPPORTED_EXTENSIONS = newHashSet("jar");
    +
         /**
    +  68   +
          * The types of files on which this will work.
     69   -
     
    +
          */
     70   -
         /**
    +
         private static final String SUPPORTED_EXTENSIONS = "jar";
     71   -
          * The analyzer should be disabled if there are errors, so this is a flag to determine if such an error has occurred.
    +
     
     72   -
          */
    -  73  2
         private boolean errorFlag = false;
    +
         /**
    +  73   +
          * The analyzer should be disabled if there are errors, so this is a flag to determine if such an error has occurred.
     74   -
     
    -  75   -
         /**
    +
          */
    +  75  24
         private boolean errorFlag = false;
     76   -
          * The searcher itself.
    +
     
     77   -
          */
    +
         /**
     78   -
         private CentralSearch searcher;
    +
          * The searcher itself.
     79   -
         /**
    +
          */
     80   -
          * Field indicating if the analyzer is enabled.
    +
         private CentralSearch searcher;
     81   -
          */
    -  82  2
         private final boolean enabled = checkEnabled();
    +
         /**
    +  82   +
          * Field indicating if the analyzer is enabled.
     83   -
     
    -  84   -
         /**
    +
          */
    +  84  24
         private final boolean enabled = checkEnabled();
     85   -
          * Determine whether to enable this analyzer or not.
    +
     
     86   -
          *
    +
         /**
     87   -
          * @return whether the analyzer should be enabled
    +
          * Determine whether to enable this analyzer or not.
     88   -
          */
    +
          *
     89   -
         @Override
    +
          * @return whether the analyzer should be enabled
     90   -
         public boolean isEnabled() {
    -  91  0
             return enabled;
    +
          */
    +  91   +
         @Override
     92   -
         }
    -  93   -
     
    +
         public boolean isEnabled() {
    +  93  0
             return enabled;
     94   -
         /**
    +
         }
     95   -
          * Determines if this analyzer is enabled.
    +
     
     96   -
          *
    +
         /**
     97   -
          * @return <code>true</code> if the analyzer is enabled; otherwise <code>false</code>
    +
          * Determines if this analyzer is enabled.
     98   -
          */
    +
          *
     99   -
         private boolean checkEnabled() {
    -  100  2
             boolean retval = false;
    +
          * @return <code>true</code> if the analyzer is enabled; otherwise <code>false</code>
    +  100   +
          */
     101   +
         private boolean checkEnabled() {
    +  102  24
             boolean retval = false;
    +  103  
     
    -  102   +  104  
             try {
    -  103  2
                 if (Settings.getBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED)) {
    -  104  1
                     if (!Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED)
    -  105   +  105  24
                 if (Settings.getBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED)) {
    +  106  16
                     if (!Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED)
    +  107  
                             || NexusAnalyzer.DEFAULT_URL.equals(Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL))) {
    -  106  1
                         LOGGER.fine("Enabling the Central analyzer");
    -  107  1
                         retval = true;
    -  108   -
                     } else {
    -  109  0
                         LOGGER.info("Nexus analyzer is enabled, disabling the Central Analyzer");
    +  108  16
                         LOGGER.debug("Enabling the Central analyzer");
    +  109  16
                         retval = true;
     110   +
                     } else {
    +  111  0
                         LOGGER.info("Nexus analyzer is enabled, disabling the Central Analyzer");
    +  112  
                     }
    -  111   -
                 } else {
    -  112  1
                     LOGGER.info("Central analyzer disabled");
     113   +
                 } else {
    +  114  8
                     LOGGER.info("Central analyzer disabled");
    +  115  
                 }
    -  114  0
             } catch (InvalidSettingException ise) {
    -  115  0
                 LOGGER.warning("Invalid setting. Disabling the Central analyzer");
    -  116  2
             }
    -  117  2
             return retval;
    -  118   -
         }
    -  119   -
     
    +  116  0
             } catch (InvalidSettingException ise) {
    +  117  0
                 LOGGER.warn("Invalid setting. Disabling the Central analyzer");
    +  118  24
             }
    +  119  24
             return retval;
     120   -
         /**
    +
         }
     121   -
          * Initializes the analyzer once before any analysis is performed.
    +
     
     122   -
          *
    +
         /**
     123   -
          * @throws Exception if there's an error during initialization
    +
          * Initializes the analyzer once before any analysis is performed.
     124   -
          */
    +
          *
     125   -
         @Override
    +
          * @throws Exception if there's an error during initialization
     126   +
          */
    +  127   +
         @Override
    +  128  
         public void initializeFileTypeAnalyzer() throws Exception {
    -  127  0
             LOGGER.fine("Initializing Central analyzer");
    -  128  0
             LOGGER.fine(String.format("Central analyzer enabled: %s", isEnabled()));
    -  129  0
             if (isEnabled()) {
    -  130  0
                 final String searchUrl = Settings.getString(Settings.KEYS.ANALYZER_CENTRAL_URL);
    -  131  0
                 LOGGER.fine(String.format("Central Analyzer URL: %s", searchUrl));
    -  132  0
                 searcher = new CentralSearch(new URL(searchUrl));
    -  133   -
             }
    -  134  0
         }
    +  129  0
             LOGGER.debug("Initializing Central analyzer");
    +  130  0
             LOGGER.debug("Central analyzer enabled: {}", isEnabled());
    +  131  0
             if (isEnabled()) {
    +  132  0
                 final String searchUrl = Settings.getString(Settings.KEYS.ANALYZER_CENTRAL_URL);
    +  133  0
                 LOGGER.debug("Central Analyzer URL: {}", searchUrl);
    +  134  0
                 searcher = new CentralSearch(new URL(searchUrl));
     135   -
     
    -  136   -
         /**
    +
             }
    +  136  0
         }
     137   -
          * Returns the analyzer's name.
    +
     
     138   -
          *
    +
         /**
     139   -
          * @return the name of the analyzer
    +
          * Returns the analyzer's name.
     140   -
          */
    +
          *
     141   -
         @Override
    +
          * @return the name of the analyzer
     142   -
         public String getName() {
    -  143  4
             return ANALYZER_NAME;
    +
          */
    +  143   +
         @Override
     144   -
         }
    -  145   -
     
    +
         public String getName() {
    +  145  32
             return ANALYZER_NAME;
     146   -
         /**
    +
         }
     147   -
          * Returns the key used in the properties file to to reference the analyzer's enabled property.
    +
     
     148   -
          *
    +
         /**
     149   -
          * @return the analyzer's enabled property setting key.
    +
          * Returns the key used in the properties file to to reference the analyzer's enabled property.
     150   -
          */
    +
          *
     151   -
         @Override
    +
          * @return the analyzer's enabled property setting key.
     152   -
         protected String getAnalyzerEnabledSettingKey() {
    -  153  2
             return Settings.KEYS.ANALYZER_CENTRAL_ENABLED;
    -  154   -
         }
    -  155   -
     
    -  156   -
         /**
    -  157   -
          * Returns the analysis phase under which the analyzer runs.
    -  158   -
          *
    -  159   -
          * @return the phase under which the analyzer runs
    -  160  
          */
    -  161   +  153  
         @Override
    -  162   -
         public AnalysisPhase getAnalysisPhase() {
    -  163  1
             return ANALYSIS_PHASE;
    -  164   +  154   +
         protected String getAnalyzerEnabledSettingKey() {
    +  155  24
             return Settings.KEYS.ANALYZER_CENTRAL_ENABLED;
    +  156  
         }
    -  165   +  157  
     
    -  166   +  158  
         /**
    -  167   -
          * Returns the extensions for which this Analyzer runs.
    -  168   +  159   +
          * Returns the analysis phase under which the analyzer runs.
    +  160  
          *
    +  161   +
          * @return the phase under which the analyzer runs
    +  162   +
          */
    +  163   +
         @Override
    +  164   +
         public AnalysisPhase getAnalysisPhase() {
    +  165  16
             return ANALYSIS_PHASE;
    +  166   +
         }
    +  167   +
     
    +  168   +
         /**
     169   -
          * @return the extensions for which this Analyzer runs
    +
          * The file filter used to determine which files this analyzer supports.
     170  
          */
    -  171   -
         @Override
    +  171  8
         private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(SUPPORTED_EXTENSIONS).build();
     172   -
         public Set<String> getSupportedExtensions() {
    -  173  0
             return SUPPORTED_EXTENSIONS;
    -  174   -
         }
    -  175  
     
    -  176   -
         /**
    -  177   -
          * Performs the analysis.
    -  178   -
          *
    -  179   -
          * @param dependency the dependency to analyze
    -  180   -
          * @param engine the engine
    -  181   -
          * @throws AnalysisException when there's an exception during analysis
    -  182   -
          */
    -  183   +  173  
         @Override
    +  174   +
         protected FileFilter getFileFilter() {
    +  175  6824
             return FILTER;
    +  176   +
         }
    +  177   +
     
    +  178   +
         /**
    +  179   +
          * Performs the analysis.
    +  180   +
          *
    +  181   +
          * @param dependency the dependency to analyze
    +  182   +
          * @param engine the engine
    +  183   +
          * @throws AnalysisException when there's an exception during analysis
     184   +
          */
    +  185   +
         @Override
    +  186  
         public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException {
    -  185  0
             if (errorFlag || !isEnabled()) {
    -  186  0
                 return;
    -  187   -
             }
    -  188   -
     
    +  187  0
             if (errorFlag || !isEnabled()) {
    +  188  0
                 return;
     189   -
             try {
    -  190  0
                 final List<MavenArtifact> mas = searcher.searchSha1(dependency.getSha1sum());
    -  191  0
                 final Confidence confidence = mas.size() > 1 ? Confidence.HIGH : Confidence.HIGHEST;
    -  192  0
                 for (MavenArtifact ma : mas) {
    -  193  0
                     LOGGER.fine(String.format("Central analyzer found artifact (%s) for dependency (%s)", ma.toString(), dependency.getFileName()));
    -  194  0
                     dependency.addAsEvidence("central", ma, confidence);
    -  195  0
                     boolean pomAnalyzed = false;
    -  196  0
                     for (Evidence e : dependency.getVendorEvidence()) {
    -  197  0
                         if ("pom".equals(e.getSource())) {
    -  198  0
                             pomAnalyzed = true;
    -  199  0
                             break;
    -  200   -
                         }
    -  201  0
                     }
    -  202  0
                     if (!pomAnalyzed && ma.getPomUrl() != null) {
    -  203  0
                         File pomFile = null;
    -  204   -
                         try {
    -  205  0
                             final File baseDir = Settings.getTempDirectory();
    -  206  0
                             pomFile = File.createTempFile("pom", ".xml", baseDir);
    -  207  0
                             if (!pomFile.delete()) {
    -  208  0
                                 final String msg = String.format("Unable to fetch pom.xml for %s from Central; "
    -  209   -
                                         + "this could result in undetected CPE/CVEs.", dependency.getFileName());
    -  210  0
                                 LOGGER.warning(msg);
    -  211  0
                                 LOGGER.fine("Unable to delete temp file");
    -  212   -
                             }
    -  213  0
                             LOGGER.fine(String.format("Downloading %s", ma.getPomUrl()));
    -  214  0
                             Downloader.fetchFile(new URL(ma.getPomUrl()), pomFile);
    -  215  0
                             PomUtils.analyzePOM(dependency, pomFile);
    -  216   +
             }
    +  190  
     
    -  217  0
                         } catch (DownloadFailedException ex) {
    -  218  0
                             final String msg = String.format("Unable to download pom.xml for %s from Central; "
    -  219   +  191   +
             try {
    +  192  0
                 final List<MavenArtifact> mas = searcher.searchSha1(dependency.getSha1sum());
    +  193  0
                 final Confidence confidence = mas.size() > 1 ? Confidence.HIGH : Confidence.HIGHEST;
    +  194  0
                 for (MavenArtifact ma : mas) {
    +  195  0
                     LOGGER.debug("Central analyzer found artifact ({}) for dependency ({})", ma.toString(), dependency.getFileName());
    +  196  0
                     dependency.addAsEvidence("central", ma, confidence);
    +  197  0
                     boolean pomAnalyzed = false;
    +  198  0
                     for (Evidence e : dependency.getVendorEvidence()) {
    +  199  0
                         if ("pom".equals(e.getSource())) {
    +  200  0
                             pomAnalyzed = true;
    +  201  0
                             break;
    +  202   +
                         }
    +  203  0
                     }
    +  204  0
                     if (!pomAnalyzed && ma.getPomUrl() != null) {
    +  205  0
                         File pomFile = null;
    +  206   +
                         try {
    +  207  0
                             final File baseDir = Settings.getTempDirectory();
    +  208  0
                             pomFile = File.createTempFile("pom", ".xml", baseDir);
    +  209  0
                             if (!pomFile.delete()) {
    +  210  0
                                 LOGGER.warn("Unable to fetch pom.xml for {} from Central; "
    +  211   +
                                         + "this could result in undetected CPE/CVEs.", dependency.getFileName());
    +  212  0
                                 LOGGER.debug("Unable to delete temp file");
    +  213   +
                             }
    +  214  0
                             LOGGER.debug("Downloading {}", ma.getPomUrl());
    +  215  0
                             Downloader.fetchFile(new URL(ma.getPomUrl()), pomFile);
    +  216  0
                             PomUtils.analyzePOM(dependency, pomFile);
    +  217   +
     
    +  218  0
                         } catch (DownloadFailedException ex) {
    +  219  0
                             LOGGER.warn("Unable to download pom.xml for {} from Central; "
    +  220  
                                     + "this could result in undetected CPE/CVEs.", dependency.getFileName());
    -  220  0
                             LOGGER.warning(msg);
     221  
                         } finally {
     222  0
                             if (pomFile != null && !FileUtils.deleteQuietly(pomFile)) {
    @@ -415,20 +417,18 @@
     
     228  0
                 }
     229  0
             } catch (IllegalArgumentException iae) {
    -  230  0
                 LOGGER.info(String.format("invalid sha1-hash on %s", dependency.getFileName()));
    +  230  0
                 LOGGER.info("invalid sha1-hash on {}", dependency.getFileName());
     231  0
             } catch (FileNotFoundException fnfe) {
    -  232  0
                 LOGGER.fine(String.format("Artifact not found in repository: '%s", dependency.getFileName()));
    +  232  0
                 LOGGER.debug("Artifact not found in repository: '{}", dependency.getFileName());
     233  0
             } catch (IOException ioe) {
    -  234  0
                 LOGGER.log(Level.FINE, "Could not connect to Central search", ioe);
    +  234  0
                 LOGGER.debug("Could not connect to Central search", ioe);
     235  0
                 errorFlag = true;
     236  0
             }
     237  0
         }
     238   -
     
    -  239  
     }
    - + 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 3ed1dc5ac..82b8c18c2 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  2
     public class CpeSuppressionAnalyzer extends AbstractSuppressionAnalyzer {
    +  31  24
     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  8
         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  1
             return ANALYSIS_PHASE;
    +  60  16
             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  16
             if (getRules() == null || getRules().size() <= 0) {
     68  0
                 return;
     69  
             }
     70  
     
    -  71  2
             for (final SuppressionRule rule : getRules()) {
    -  72  34
                 rule.process(dependency);
    -  73  34
             }
    -  74  2
         }
    +  71  16
             for (final SuppressionRule rule : getRules()) {
    +  72  304
                 rule.process(dependency);
    +  73  304
             }
    +  74  16
         }
     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 e05c4bbba..c22cc38a7 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
    41%
    63/151
    33%
    53/158
    7.923
    DependencyBundlingAnalyzer
    42%
    63/148
    31%
    51/160
    7.5
     
    @@ -66,167 +66,167 @@  24  
     import java.util.Set;
     25   -
     import java.util.logging.Level;
    -  26   -
     import java.util.logging.Logger;
    -  27  
     import java.util.regex.Matcher;
    -  28   +  26  
     import java.util.regex.Pattern;
    -  29   +  27  
     import org.owasp.dependencycheck.Engine;
    -  30   +  28  
     import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
    -  31   +  29  
     import org.owasp.dependencycheck.dependency.Dependency;
    -  32   +  30  
     import org.owasp.dependencycheck.dependency.Identifier;
    -  33   +  31  
     import org.owasp.dependencycheck.utils.DependencyVersion;
    -  34   +  32  
     import org.owasp.dependencycheck.utils.DependencyVersionUtil;
    +  33   +
     import org.slf4j.Logger;
    +  34   +
     import org.slf4j.LoggerFactory;
     35   -
     import org.owasp.dependencycheck.utils.LogUtils;
    +
     
     36   -
     
    -  37  
     /**
    +  37   +
      * <p>
     38   -
      * <p>
    -  39  
      * This analyzer ensures dependencies that should be grouped together, to remove excess noise from the report, are grouped. An
    -  40   +  39  
      * example would be Spring, Spring Beans, Spring MVC, etc. If they are all for the same version and have the same relative path
    -  41   +  40  
      * then these should be grouped into a single dependency under the core/main library.</p>
    -  42   +  41  
      * <p>
    -  43   +  42  
      * Note, this grouping only works on dependencies with identified CVE entries</p>
    -  44   +  43  
      *
    -  45   +  44  
      * @author Jeremy Long
    -  46   +  45  
      */
    -  47  6
     public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Analyzer {
    +  46  56
     public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Analyzer {
    +  47   +
     
     48   -
     
    +
         /**
     49   -
         /**
    -  50  
          * The Logger.
    -  51   +  50  
          */
    -  52  1
         private static final Logger LOGGER = Logger.getLogger(DependencyBundlingAnalyzer.class.getName());
    +  51  8
         private static final Logger LOGGER = LoggerFactory.getLogger(DependencyBundlingAnalyzer.class);
    +  52   +
     
     53   -
     
    -  54  
         //<editor-fold defaultstate="collapsed" desc="Constants and Member Variables">
    +  54   +
         /**
     55   -
         /**
    -  56  
          * A pattern for obtaining the first part of a filename.
    -  57   +  56  
          */
    -  58  1
         private static final Pattern STARTING_TEXT_PATTERN = Pattern.compile("^[a-zA-Z0-9]*");
    +  57  8
         private static final Pattern STARTING_TEXT_PATTERN = Pattern.compile("^[a-zA-Z0-9]*");
    +  58   +
         /**
     59   -
         /**
    -  60  
          * a flag indicating if this analyzer has run. This analyzer only runs once.
    -  61   +  60  
          */
    -  62  6
         private boolean analyzed = false;
    +  61  56
         private boolean analyzed = false;
    +  62   +
         //</editor-fold>
     63   -
         //</editor-fold>
    -  64  
         //<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer">
    +  64   +
         /**
     65   -
         /**
    -  66  
          * The name of the analyzer.
    +  66   +
          */
     67   -
          */
    -  68  
         private static final String ANALYZER_NAME = "Dependency Bundling Analyzer";
    +  68   +
         /**
     69   -
         /**
    -  70  
          * The phase that this analyzer is intended to run in.
    -  71   +  70  
          */
    -  72  1
         private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_FINDING_ANALYSIS;
    +  71  8
         private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_FINDING_ANALYSIS;
    +  72   +
     
     73   -
     
    +
         /**
     74   -
         /**
    -  75  
          * Returns the name of the analyzer.
    +  75   +
          *
     76   -
          *
    -  77  
          * @return the name of the analyzer.
    +  77   +
          */
     78   -
          */
    -  79  
         public String getName() {
    -  80  5
             return ANALYZER_NAME;
    +  79  40
             return ANALYZER_NAME;
    +  80   +
         }
     81   -
         }
    +
     
     82   -
     
    +
         /**
     83   -
         /**
    -  84  
          * Returns the phase that the analyzer is intended to run in.
    +  84   +
          *
     85   -
          *
    -  86  
          * @return the phase that the analyzer is intended to run in.
    +  86   +
          */
     87   -
          */
    -  88  
         public AnalysisPhase getAnalysisPhase() {
    -  89  2
             return ANALYSIS_PHASE;
    -  90   +  88  24
             return ANALYSIS_PHASE;
    +  89  
         }
    -  91   +  90  
         //</editor-fold>
    -  92   +  91  
     
    -  93   +  92  
         /**
    -  94   +  93  
          * Analyzes a set of dependencies. If they have been found to have the same base path and the same set of identifiers they are
    -  95   +  94  
          * likely related. The related dependencies are bundled into a single reportable item.
    -  96   +  95  
          *
    -  97   +  96  
          * @param ignore this analyzer ignores the dependency being analyzed
    -  98   +  97  
          * @param engine the engine that is scanning the dependencies
    -  99   +  98  
          * @throws AnalysisException is thrown if there is an error reading the JAR file.
    -  100   +  99  
          */
    -  101   +  100  
         @Override
    -  102   +  101  
         public void analyze(Dependency ignore, Engine engine) throws AnalysisException {
    -  103  2
             if (!analyzed) {
    -  104  1
                 analyzed = true;
    -  105  1
                 final Set<Dependency> dependenciesToRemove = new HashSet<Dependency>();
    -  106  1
                 final ListIterator<Dependency> mainIterator = engine.getDependencies().listIterator();
    -  107   +  102  16
             if (!analyzed) {
    +  103  8
                 analyzed = true;
    +  104  8
                 final Set<Dependency> dependenciesToRemove = new HashSet<Dependency>();
    +  105  8
                 final ListIterator<Dependency> mainIterator = engine.getDependencies().listIterator();
    +  106  
                 //for (Dependency nextDependency : engine.getDependencies()) {
    -  108  3
                 while (mainIterator.hasNext()) {
    -  109  2
                     final Dependency dependency = mainIterator.next();
    -  110  2
                     if (mainIterator.hasNext() && !dependenciesToRemove.contains(dependency)) {
    -  111  1
                         final ListIterator<Dependency> subIterator = engine.getDependencies().listIterator(mainIterator.nextIndex());
    -  112  2
                         while (subIterator.hasNext()) {
    -  113  1
                             final Dependency nextDependency = subIterator.next();
    -  114  1
                             if (hashesMatch(dependency, nextDependency)) {
    +  107  24
                 while (mainIterator.hasNext()) {
    +  108  16
                     final Dependency dependency = mainIterator.next();
    +  109  16
                     if (mainIterator.hasNext() && !dependenciesToRemove.contains(dependency)) {
    +  110  8
                         final ListIterator<Dependency> subIterator = engine.getDependencies().listIterator(mainIterator.nextIndex());
    +  111  16
                         while (subIterator.hasNext()) {
    +  112  8
                             final Dependency nextDependency = subIterator.next();
    +  113  8
                             if (hashesMatch(dependency, nextDependency) && !containedInWar(dependency.getFilePath())
    +  114   +
                                     && !containedInWar(nextDependency.getFilePath())) {
     115  0
                                 if (firstPathIsShortest(dependency.getFilePath(), nextDependency.getFilePath())) {
     116  0
                                     mergeDependencies(dependency, nextDependency, dependenciesToRemove);
     117   @@ -235,7 +235,7 @@  119  0
                                     break; //since we merged into the next dependency - skip forward to the next in mainIterator
     120  
                                 }
    -  121  1
                             } else if (isShadedJar(dependency, nextDependency)) {
    +  121  8
                             } else if (isShadedJar(dependency, nextDependency)) {
     122  0
                                 if (dependency.getFileName().toLowerCase().endsWith("pom.xml")) {
     123  0
                                     mergeDependencies(nextDependency, dependency, dependenciesToRemove);
     124  0
                                     nextDependency.getRelatedDependencies().remove(dependency);
    @@ -243,10 +243,10 @@  126  
                                 } else {
     127  0
                                     mergeDependencies(dependency, nextDependency, dependenciesToRemove);
    -  128  0
                                     nextDependency.getRelatedDependencies().remove(nextDependency);
    +  128  0
                                     dependency.getRelatedDependencies().remove(nextDependency);
     129  
                                 }
    -  130  1
                             } else if (cpeIdentifiersMatch(dependency, nextDependency)
    +  130  8
                             } else if (cpeIdentifiersMatch(dependency, nextDependency)
     131  
                                     && hasSameBasePath(dependency, nextDependency)
     132   @@ -261,18 +261,18 @@
                                 }
     139  
                             }
    -  140  1
                         }
    +  140  8
                         }
     141  
                     }
    -  142  2
                 }
    +  142  16
                 }
     143  
                 //removing dependencies here as ensuring correctness and avoiding ConcurrentUpdateExceptions
     144  
                 // was difficult because of the inner iterator.
    -  145  1
                 engine.getDependencies().removeAll(dependenciesToRemove);
    +  145  8
                 engine.getDependencies().removeAll(dependenciesToRemove);
     146  
             }
    -  147  2
         }
    +  147  16
         }
     148  
     
     149   @@ -418,28 +418,28 @@
          */
     237  
         private boolean cpeIdentifiersMatch(Dependency dependency1, Dependency dependency2) {
    -  238  1
             if (dependency1 == null || dependency1.getIdentifiers() == null
    +  238  8
             if (dependency1 == null || dependency1.getIdentifiers() == null
     239  
                     || dependency2 == null || dependency2.getIdentifiers() == null) {
     240  0
                 return false;
     241  
             }
    -  242  1
             boolean matches = false;
    -  243  1
             int cpeCount1 = 0;
    -  244  1
             int cpeCount2 = 0;
    -  245  1
             for (Identifier i : dependency1.getIdentifiers()) {
    +  242  8
             boolean matches = false;
    +  243  8
             int cpeCount1 = 0;
    +  244  8
             int cpeCount2 = 0;
    +  245  8
             for (Identifier i : dependency1.getIdentifiers()) {
     246  0
                 if ("cpe".equals(i.getType())) {
     247  0
                     cpeCount1 += 1;
     248  
                 }
     249  0
             }
    -  250  1
             for (Identifier i : dependency2.getIdentifiers()) {
    -  251  2
                 if ("cpe".equals(i.getType())) {
    -  252  2
                     cpeCount2 += 1;
    +  250  8
             for (Identifier i : dependency2.getIdentifiers()) {
    +  251  24
                 if ("cpe".equals(i.getType())) {
    +  252  24
                     cpeCount2 += 1;
     253  
                 }
    -  254  2
             }
    -  255  1
             if (cpeCount1 > 0 && cpeCount1 == cpeCount2) {
    +  254  24
             }
    +  255  8
             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);
    @@ -452,270 +452,281 @@  263  0
                 }
     264  
             }
    -  265  1
             if (LogUtils.isVerboseLoggingEnabled()) {
    -  266  0
                 final String msg = String.format("IdentifiersMatch=%s (%s, %s)", matches, dependency1.getFileName(), dependency2.getFileName());
    -  267  0
                 LOGGER.log(Level.FINE, msg);
    -  268   -
             }
    -  269  1
             return matches;
    -  270   +  265  8
             LOGGER.debug("IdentifiersMatch={} ({}, {})", matches, dependency1.getFileName(), dependency2.getFileName());
    +  266  8
             return matches;
    +  267  
         }
    -  271   +  268  
     
    -  272   +  269  
         /**
    -  273   +  270  
          * Determines if the two dependencies have the same base path.
    -  274   +  271  
          *
    -  275   +  272  
          * @param dependency1 a Dependency object
    -  276   +  273  
          * @param dependency2 a Dependency object
    -  277   +  274  
          * @return true if the base paths of the dependencies are identical
    -  278   +  275  
          */
    -  279   +  276  
         private boolean hasSameBasePath(Dependency dependency1, Dependency dependency2) {
    -  280  0
             if (dependency1 == null || dependency2 == null) {
    -  281  0
                 return false;
    -  282   +  277  0
             if (dependency1 == null || dependency2 == null) {
    +  278  0
                 return false;
    +  279  
             }
    -  283  0
             final File lFile = new File(dependency1.getFilePath());
    -  284  0
             String left = lFile.getParent();
    -  285  0
             final File rFile = new File(dependency2.getFilePath());
    -  286  0
             String right = rFile.getParent();
    -  287  0
             if (left == null) {
    -  288  0
                 return right == null;
    +  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.equalsIgnoreCase(right)) {
    -  291  0
                 return true;
    -  292   +  290  0
             if (left.matches(".*[/\\\\]repository[/\\\\].*") && right.matches(".*[/\\\\]repository[/\\\\].*")) {
    +  291  0
                 left = getBaseRepoPath(left);
    +  292  0
                 right = getBaseRepoPath(right);
    +  293  
             }
    -  293  0
             if (left.matches(".*[/\\\\]repository[/\\\\].*") && right.matches(".*[/\\\\]repository[/\\\\].*")) {
    -  294  0
                 left = getBaseRepoPath(left);
    -  295  0
                 right = getBaseRepoPath(right);
    +  294  0
             if (left.equalsIgnoreCase(right)) {
    +  295  0
                 return true;
     296  
             }
    -  297  0
             if (left.equalsIgnoreCase(right)) {
    -  298  0
                 return true;
    -  299   -
             }
    -  300   +  297  
             //new code
    -  301  0
             for (Dependency child : dependency2.getRelatedDependencies()) {
    -  302  0
                 if (hasSameBasePath(dependency1, child)) {
    -  303  0
                     return true;
    +  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   -
                 }
    -  305  0
             }
    -  306  0
             return false;
    +
         }
    +  305   +
     
    +  306   +
         /**
     307   -
         }
    -  308   -
     
    -  309   -
         /**
    -  310  
          * This is likely a very broken attempt at determining if the 'left' dependency is the 'core' library in comparison to the
    -  311   +  308  
          * 'right' library.
    -  312   +  309  
          *
    -  313   +  310  
          * @param left the dependency to test
    -  314   +  311  
          * @param right the dependency to test against
    -  315   +  312  
          * @return a boolean indicating whether or not the left dependency should be considered the "core" version.
    -  316   +  313  
          */
    -  317   +  314  
         boolean isCore(Dependency left, Dependency right) {
    -  318  2
             final String leftName = left.getFileName().toLowerCase();
    -  319  2
             final String rightName = right.getFileName().toLowerCase();
    -  320   +  315  16
             final String leftName = left.getFileName().toLowerCase();
    +  316  16
             final String rightName = right.getFileName().toLowerCase();
    +  317  
     
    -  321   +  318  
             final boolean returnVal;
    -  322  2
             if (!rightName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+") && leftName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+")
    -  323   +  319  16
             if (!rightName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+") && leftName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+")
    +  320  
                     || rightName.contains("core") && !leftName.contains("core")
    -  324   +  321  
                     || rightName.contains("kernel") && !leftName.contains("kernel")) {
    -  325  0
                 returnVal = false;
    -  326  2
             } else if (rightName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+") && !leftName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+")
    -  327   +  322  0
                 returnVal = false;
    +  323  16
             } 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")
    -  328   +  325  
                     || !rightName.contains("kernel") && leftName.contains("kernel")) {
    -  329  2
                 returnVal = true;
    -  330   +  326  16
                 returnVal = true;
    +  327  
     //        } else if (leftName.matches(".*struts2\\-core.*") && rightName.matches(".*xwork\\-core.*")) {
    -  331   +  328  
     //            returnVal = true;
    -  332   +  329  
     //        } else if (rightName.matches(".*struts2\\-core.*") && leftName.matches(".*xwork\\-core.*")) {
    -  333   +  330  
     //            returnVal = false;
    -  334   +  331  
             } else {
    -  335   +  332  
                 /*
    -  336   +  333  
                  * considered splitting the names up and comparing the components,
    -  337   +  334  
                  * but decided that the file name length should be sufficient as the
    -  338   +  335  
                  * "core" component, if this follows a normal naming protocol should
    -  339   +  336  
                  * be shorter:
    -  340   +  337  
                  * axis2-saaj-1.4.1.jar
    -  341   +  338  
                  * axis2-1.4.1.jar       <-----
    -  342   +  339  
                  * axis2-kernel-1.4.1.jar
    -  343   +  340  
                  */
    -  344  0
                 returnVal = leftName.length() <= rightName.length();
    +  341  0
                 returnVal = leftName.length() <= rightName.length();
    +  342   +
             }
    +  343  16
             LOGGER.debug("IsCore={} ({}, {})", returnVal, left.getFileName(), right.getFileName());
    +  344  16
             return returnVal;
     345   -
             }
    -  346  2
             if (LogUtils.isVerboseLoggingEnabled()) {
    -  347  0
                 final String msg = String.format("IsCore=%s (%s, %s)", returnVal, left.getFileName(), right.getFileName());
    -  348  0
                 LOGGER.log(Level.FINE, msg);
    -  349   -
             }
    -  350  2
             return returnVal;
    -  351  
         }
    -  352   +  346  
     
    -  353   +  347  
         /**
    -  354   +  348  
          * Compares the SHA1 hashes of two dependencies to determine if they are equal.
    -  355   +  349  
          *
    -  356   +  350  
          * @param dependency1 a dependency object to compare
    -  357   +  351  
          * @param dependency2 a dependency object to compare
    -  358   +  352  
          * @return true if the sha1 hashes of the two dependencies match; otherwise false
    -  359   +  353  
          */
    -  360   +  354  
         private boolean hashesMatch(Dependency dependency1, Dependency dependency2) {
    -  361  1
             if (dependency1 == null || dependency2 == null || dependency1.getSha1sum() == null || dependency2.getSha1sum() == null) {
    -  362  0
                 return false;
    -  363   +  355  8
             if (dependency1 == null || dependency2 == null || dependency1.getSha1sum() == null || dependency2.getSha1sum() == null) {
    +  356  0
                 return false;
    +  357  
             }
    -  364  1
             return dependency1.getSha1sum().equals(dependency2.getSha1sum());
    -  365   +  358  8
             return dependency1.getSha1sum().equals(dependency2.getSha1sum());
    +  359  
         }
    -  366   +  360  
     
    -  367   +  361  
         /**
    -  368   +  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
    -  369   +  363  
          * should be removed.
    -  370   +  364  
          *
    -  371   +  365  
          * @param dependency a dependency to check
    -  372   +  366  
          * @param nextDependency another dependency to check
    -  373   +  367  
          * @return true if on of the dependencies is a pom.xml and the identifiers between the two collections match; otherwise false
    -  374   +  368  
          */
    -  375   +  369  
         private boolean isShadedJar(Dependency dependency, Dependency nextDependency) {
    -  376  1
             final String mainName = dependency.getFileName().toLowerCase();
    -  377  1
             final String nextName = nextDependency.getFileName().toLowerCase();
    -  378  1
             if (mainName.endsWith(".jar") && nextName.endsWith("pom.xml")) {
    -  379  0
                 return dependency.getIdentifiers().containsAll(nextDependency.getIdentifiers());
    -  380  1
             } else if (nextName.endsWith(".jar") && mainName.endsWith("pom.xml")) {
    -  381  0
                 return nextDependency.getIdentifiers().containsAll(dependency.getIdentifiers());
    -  382   +  370  8
             final String mainName = dependency.getFileName().toLowerCase();
    +  371  8
             final String nextName = nextDependency.getFileName().toLowerCase();
    +  372  8
             if (mainName.endsWith(".jar") && nextName.endsWith("pom.xml")) {
    +  373  0
                 return dependency.getIdentifiers().containsAll(nextDependency.getIdentifiers());
    +  374  8
             } else if (nextName.endsWith(".jar") && mainName.endsWith("pom.xml")) {
    +  375  0
                 return nextDependency.getIdentifiers().containsAll(dependency.getIdentifiers());
    +  376  
             }
    -  383  1
             return false;
    -  384   +  377  8
             return false;
    +  378  
         }
    -  385   +  379  
     
    -  386   +  380  
         /**
    -  387   +  381  
          * Determines which path is shortest; if path lengths are equal then we use compareTo of the string method to determine if the
    -  388   +  382  
          * first path is smaller.
    -  389   +  383  
          *
    -  390   +  384  
          * @param left the first path to compare
    -  391   +  385  
          * @param right the second path to compare
    -  392   +  386  
          * @return <code>true</code> if the leftPath is the shortest; otherwise <code>false</code>
    -  393   +  387  
          */
    -  394   +  388  
         protected boolean firstPathIsShortest(String left, String right) {
    -  395  5
             final String leftPath = left.replace('\\', '/');
    -  396  5
             final String rightPath = right.replace('\\', '/');
    -  397   +  389  40
             final String leftPath = left.replace('\\', '/');
    +  390  40
             final String rightPath = right.replace('\\', '/');
    +  391  
     
    -  398  5
             final int leftCount = countChar(leftPath, '/');
    -  399  5
             final int rightCount = countChar(rightPath, '/');
    -  400  5
             if (leftCount == rightCount) {
    -  401  3
                 return leftPath.compareTo(rightPath) <= 0;
    -  402   +  392  40
             final int leftCount = countChar(leftPath, '/');
    +  393  40
             final int rightCount = countChar(rightPath, '/');
    +  394  40
             if (leftCount == rightCount) {
    +  395  24
                 return leftPath.compareTo(rightPath) <= 0;
    +  396  
             } else {
    -  403  2
                 return leftCount < rightCount;
    -  404   +  397  16
                 return leftCount < rightCount;
    +  398  
             }
    -  405   +  399  
         }
    -  406   +  400  
     
    -  407   +  401  
         /**
    -  408   +  402  
          * Counts the number of times the character is present in the string.
    -  409   +  403  
          *
    -  410   +  404  
          * @param string the string to count the characters in
    -  411   +  405  
          * @param c the character to count
    -  412   +  406  
          * @return the number of times the character is present in the string
    -  413   +  407  
          */
    -  414   +  408  
         private int countChar(String string, char c) {
    -  415  10
             int count = 0;
    -  416  10
             final int max = string.length();
    -  417  116
             for (int i = 0; i < max; i++) {
    -  418  106
                 if (c == string.charAt(i)) {
    -  419  28
                     count++;
    -  420   +  409  80
             int count = 0;
    +  410  80
             final int max = string.length();
    +  411  928
             for (int i = 0; i < max; i++) {
    +  412  848
                 if (c == string.charAt(i)) {
    +  413  224
                     count++;
    +  414  
                 }
    -  421   +  415  
             }
    -  422  10
             return count;
    -  423   +  416  80
             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  0
             return filePath == null ? false : filePath.matches(".*\\.(ear|war)[\\\\/].*");
    +  427   +
         }
    +  428  
     }
    - + 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 5b53149a2..40a8bfad2 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.FalsePositiveAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.FalsePositiveAnalyzer.html @@ -12,7 +12,7 @@
     
    - +
    Classes in this File Line Coverage Branch Coverage Complexity
    FalsePositiveAnalyzer
    49%
    87/176
    27%
    58/212
    9.692
    FalsePositiveAnalyzer
    49%
    88/177
    25%
    58/230
    10.385
     
    @@ -56,729 +56,760 @@  19  
     
     20   -
     import java.io.UnsupportedEncodingException;
    +
     import java.io.FileFilter;
     21   -
     import java.net.URLEncoder;
    +
     import java.io.UnsupportedEncodingException;
     22   -
     import java.util.ArrayList;
    +
     import java.net.URLEncoder;
     23   -
     import java.util.Collections;
    +
     import java.util.ArrayList;
     24   -
     import java.util.Iterator;
    +
     import java.util.Collections;
     25   -
     import java.util.List;
    +
     import java.util.Iterator;
     26   -
     import java.util.ListIterator;
    +
     import java.util.List;
     27   -
     import java.util.Set;
    +
     import java.util.ListIterator;
     28   -
     import java.util.logging.Level;
    +
     import java.util.Set;
     29   -
     import java.util.logging.Logger;
    -  30  
     import java.util.regex.Matcher;
    -  31   +  30  
     import java.util.regex.Pattern;
    -  32   +  31  
     import org.owasp.dependencycheck.Engine;
    -  33   +  32  
     import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
    -  34   +  33  
     import org.owasp.dependencycheck.dependency.Dependency;
    -  35   +  34  
     import org.owasp.dependencycheck.dependency.Identifier;
    -  36   +  35  
     import org.owasp.dependencycheck.dependency.VulnerableSoftware;
    +  36   +
     import org.owasp.dependencycheck.utils.FileFilterBuilder;
     37   -
     
    +
     import org.slf4j.Logger;
     38   -
     /**
    +
     import org.slf4j.LoggerFactory;
     39   -
      * This analyzer attempts to remove some well known false positives - specifically regarding the java runtime.
    +
     
     40   -
      *
    +
     /**
     41   -
      * @author Jeremy Long
    +
      * This analyzer attempts to remove some well known false positives - specifically regarding the java runtime.
     42   -
      */
    -  43  5
     public class FalsePositiveAnalyzer extends AbstractAnalyzer {
    +
      *
    +  43   +
      * @author Jeremy Long
     44   -
     
    -  45   -
         /**
    +
      */
    +  45  48
     public class FalsePositiveAnalyzer extends AbstractAnalyzer {
     46   -
          * The Logger.
    +
     
     47   -
          */
    -  48  1
         private static final Logger LOGGER = Logger.getLogger(FalsePositiveAnalyzer.class.getName());
    +
         /**
    +  48   +
          * The Logger.
     49   -
         //<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer">
    -  50   -
         /**
    +
          */
    +  50  8
         private static final Logger LOGGER = LoggerFactory.getLogger(FalsePositiveAnalyzer.class);
     51   -
          * The name of the analyzer.
    +
     
     52   -
          */
    +
         /**
     53   -
         private static final String ANALYZER_NAME = "False Positive Analyzer";
    +
          * The file filter used to find DLL and EXE.
     54   -
         /**
    -  55   -
          * The phase that this analyzer is intended to run in.
    +
          */
    +  55  8
         private static final FileFilter DLL_EXE_FILTER = FileFilterBuilder.newInstance().addExtensions("dll", "exe").build();
     56   -
          */
    -  57  1
         private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.POST_IDENTIFIER_ANALYSIS;
    +
     
    +  57   +
         //<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer">
     58   -
     
    +
         /**
     59   -
         /**
    +
          * The name of the analyzer.
     60   -
          * Returns the name of the analyzer.
    +
          */
     61   -
          *
    +
         private static final String ANALYZER_NAME = "False Positive Analyzer";
     62   -
          * @return the name of the analyzer.
    +
         /**
     63   -
          */
    +
          * The phase that this analyzer is intended to run in.
     64   -
         public String getName() {
    -  65  5
             return ANALYZER_NAME;
    +
          */
    +  65  8
         private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.POST_IDENTIFIER_ANALYSIS;
     66   -
         }
    +
     
     67   -
     
    +
         /**
     68   -
         /**
    +
          * Returns the name of the analyzer.
     69   -
          * Returns the phase that the analyzer is intended to run in.
    +
          *
     70   -
          *
    +
          * @return the name of the analyzer.
     71   -
          * @return the phase that the analyzer is intended to run in.
    +
          */
     72   -
          */
    -  73   -
         public AnalysisPhase getAnalysisPhase() {
    -  74  2
             return ANALYSIS_PHASE;
    -  75   +
         public String getName() {
    +  73  40
             return ANALYZER_NAME;
    +  74  
         }
    +  75   +
     
     76   -
         //</editor-fold>
    +
         /**
     77   -
     
    +
          * Returns the phase that the analyzer is intended to run in.
     78   -
         /**
    +
          *
     79   -
          * Analyzes the dependencies and removes bad/incorrect CPE associations based on various heuristics.
    +
          * @return the phase that the analyzer is intended to run in.
     80   -
          *
    +
          */
     81   -
          * @param dependency the dependency to analyze.
    -  82   -
          * @param engine the engine that is scanning the dependencies
    +
         public AnalysisPhase getAnalysisPhase() {
    +  82  24
             return ANALYSIS_PHASE;
     83   -
          * @throws AnalysisException is thrown if there is an error reading the JAR file.
    +
         }
     84   -
          */
    +
         //</editor-fold>
     85   -
         @Override
    +
     
     86   +
         /**
    +  87   +
          * Analyzes the dependencies and removes bad/incorrect CPE associations based on various heuristics.
    +  88   +
          *
    +  89   +
          * @param dependency the dependency to analyze.
    +  90   +
          * @param engine the engine that is scanning the dependencies
    +  91   +
          * @throws AnalysisException is thrown if there is an error reading the JAR file.
    +  92   +
          */
    +  93   +
         @Override
    +  94  
         public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
    -  87  3
             removeJreEntries(dependency);
    -  88  3
             removeBadMatches(dependency);
    -  89  3
             removeBadSpringMatches(dependency);
    -  90  3
             removeWrongVersionMatches(dependency);
    -  91  3
             removeSpuriousCPE(dependency);
    -  92  3
             removeDuplicativeEntriesFromJar(dependency, engine);
    -  93  3
             addFalseNegativeCPEs(dependency);
    -  94  3
         }
    -  95   +  95  24
             removeJreEntries(dependency);
    +  96  24
             removeBadMatches(dependency);
    +  97  24
             removeBadSpringMatches(dependency);
    +  98  24
             removeWrongVersionMatches(dependency);
    +  99  24
             removeSpuriousCPE(dependency);
    +  100  24
             removeDuplicativeEntriesFromJar(dependency, engine);
    +  101  24
             addFalseNegativeCPEs(dependency);
    +  102  24
         }
    +  103  
     
    -  96   +  104  
         /**
    -  97   +  105  
          * Removes inaccurate matches on springframework CPEs.
    -  98   +  106  
          *
    -  99   +  107  
          * @param dependency the dependency to test for and remove known inaccurate CPE matches
    -  100   +  108  
          */
    -  101   +  109  
         private void removeBadSpringMatches(Dependency dependency) {
    -  102  3
             String mustContain = null;
    -  103  3
             for (Identifier i : dependency.getIdentifiers()) {
    -  104  2
                 if ("maven".contains(i.getType())) {
    -  105  0
                     if (i.getValue() != null && i.getValue().startsWith("org.springframework.")) {
    -  106  0
                         final int endPoint = i.getValue().indexOf(":", 19);
    -  107  0
                         if (endPoint >= 0) {
    -  108  0
                             mustContain = i.getValue().substring(19, endPoint).toLowerCase();
    -  109  0
                             break;
    -  110   +  110  24
             String mustContain = null;
    +  111  24
             for (Identifier i : dependency.getIdentifiers()) {
    +  112  24
                 if ("maven".contains(i.getType())) {
    +  113  0
                     if (i.getValue() != null && i.getValue().startsWith("org.springframework.")) {
    +  114  0
                         final int endPoint = i.getValue().indexOf(":", 19);
    +  115  0
                         if (endPoint >= 0) {
    +  116  0
                             mustContain = i.getValue().substring(19, endPoint).toLowerCase();
    +  117  0
                             break;
    +  118  
                         }
    -  111   -
                     }
    -  112   -
                 }
    -  113  2
             }
    -  114  3
             if (mustContain != null) {
    -  115  0
                 final Iterator<Identifier> itr = dependency.getIdentifiers().iterator();
    -  116  0
                 while (itr.hasNext()) {
    -  117  0
                     final Identifier i = itr.next();
    -  118  0
                     if ("cpe".contains(i.getType())
     119   -
                             && i.getValue() != null
    +
                     }
     120   -
                             && i.getValue().startsWith("cpe:/a:springsource:")
    -  121   -
                             && !i.getValue().toLowerCase().contains(mustContain)) {
    -  122  0
                         itr.remove();
    -  123   -
                         //dependency.getIdentifiers().remove(i);
    -  124   -
                     }
    -  125  0
                 }
    -  126   -
             }
    -  127  3
         }
    -  128   -
     
    -  129   -
         /**
    -  130   -
          * <p>
    -  131   -
          * Intended to remove spurious CPE entries. By spurious we mean duplicate, less specific CPE entries.</p>
    -  132   -
          * <p>
    -  133   -
          * Example:</p>
    -  134   -
          * <code>
    -  135   -
          * cpe:/a:some-vendor:some-product
    -  136   -
          * cpe:/a:some-vendor:some-product:1.5
    -  137   -
          * cpe:/a:some-vendor:some-product:1.5.2
    -  138   -
          * </code>
    -  139   -
          * <p>
    -  140   -
          * Should be trimmed to:</p>
    -  141   -
          * <code>
    -  142   -
          * cpe:/a:some-vendor:some-product:1.5.2
    -  143   -
          * </code>
    -  144   -
          *
    -  145   -
          * @param dependency the dependency being analyzed
    -  146   -
          */
    -  147   -
         @SuppressWarnings("null")
    -  148   -
         private void removeSpuriousCPE(Dependency dependency) {
    -  149  3
             final List<Identifier> ids = new ArrayList<Identifier>();
    -  150  3
             ids.addAll(dependency.getIdentifiers());
    -  151  3
             Collections.sort(ids);
    -  152  3
             final ListIterator<Identifier> mainItr = ids.listIterator();
    -  153  5
             while (mainItr.hasNext()) {
    -  154  2
                 final Identifier currentId = mainItr.next();
    -  155  2
                 final VulnerableSoftware currentCpe = parseCpe(currentId.getType(), currentId.getValue());
    -  156  2
                 if (currentCpe == null) {
    -  157  0
                     continue;
    -  158  
                 }
    -  159  2
                 final ListIterator<Identifier> subItr = ids.listIterator(mainItr.nextIndex());
    -  160  3
                 while (subItr.hasNext()) {
    -  161  1
                     final Identifier nextId = subItr.next();
    -  162  1
                     final VulnerableSoftware nextCpe = parseCpe(nextId.getType(), nextId.getValue());
    -  163  1
                     if (nextCpe == null) {
    -  164  0
                         continue;
    -  165   +  121  24
             }
    +  122  24
             if (mustContain != null) {
    +  123  0
                 final Iterator<Identifier> itr = dependency.getIdentifiers().iterator();
    +  124  0
                 while (itr.hasNext()) {
    +  125  0
                     final Identifier i = itr.next();
    +  126  0
                     if ("cpe".contains(i.getType())
    +  127   +
                             && i.getValue() != null
    +  128   +
                             && i.getValue().startsWith("cpe:/a:springsource:")
    +  129   +
                             && !i.getValue().toLowerCase().contains(mustContain)) {
    +  130  0
                         itr.remove();
    +  131   +
                         //dependency.getIdentifiers().remove(i);
    +  132  
                     }
    -  166   -
                     //TODO fix the version problem below
    -  167  1
                     if (currentCpe.getVendor().equals(nextCpe.getVendor())) {
    -  168  0
                         if (currentCpe.getProduct().equals(nextCpe.getProduct())) {
    -  169   -
                             // see if one is contained in the other.. remove the contained one from dependency.getIdentifier
    -  170  0
                             final String currentVersion = currentCpe.getVersion();
    -  171  0
                             final String nextVersion = nextCpe.getVersion();
    -  172  0
                             if (currentVersion == null && nextVersion == null) {
    -  173   -
                                 //how did we get here?
    -  174  0
                                 LOGGER.log(Level.FINE, "currentVersion and nextVersion are both null?");
    -  175  0
                             } else if (currentVersion == null && nextVersion != null) {
    -  176  0
                                 dependency.getIdentifiers().remove(currentId);
    -  177  0
                             } else if (nextVersion == null && currentVersion != null) {
    -  178  0
                                 dependency.getIdentifiers().remove(nextId);
    -  179  0
                             } else if (currentVersion.length() < nextVersion.length()) {
    -  180  0
                                 if (nextVersion.startsWith(currentVersion) || "-".equals(currentVersion)) {
    -  181  0
                                     dependency.getIdentifiers().remove(currentId);
    -  182   -
                                 }
    -  183   -
                             } else {
    -  184  0
                                 if (currentVersion.startsWith(nextVersion) || "-".equals(nextVersion)) {
    -  185  0
                                     dependency.getIdentifiers().remove(nextId);
    -  186   -
                                 }
    -  187   -
                             }
    -  188   -
                         }
    -  189   -
                     }
    -  190  1
                 }
    -  191  2
             }
    -  192  3
         }
    -  193   -
         /**
    -  194   -
          * Regex to identify core java libraries and a few other commonly misidentified ones.
    -  195   -
          */
    -  196  1
         public static final Pattern CORE_JAVA = Pattern.compile("^cpe:/a:(sun|oracle|ibm):(j2[ems]e|"
    -  197   -
                 + "java(_platform_micro_edition|_runtime_environment|_se|virtual_machine|se_development_kit|fx)?|"
    -  198   -
                 + "jdk|jre|jsse)($|:.*)");
    -  199   +  133  0
                 }
    +  134   +
             }
    +  135  24
         }
    +  136  
     
    -  200   +  137  
         /**
    +  138   +
          * <p>
    +  139   +
          * Intended to remove spurious CPE entries. By spurious we mean duplicate, less specific CPE entries.</p>
    +  140   +
          * <p>
    +  141   +
          * Example:</p>
    +  142   +
          * <code>
    +  143   +
          * cpe:/a:some-vendor:some-product
    +  144   +
          * cpe:/a:some-vendor:some-product:1.5
    +  145   +
          * cpe:/a:some-vendor:some-product:1.5.2
    +  146   +
          * </code>
    +  147   +
          * <p>
    +  148   +
          * Should be trimmed to:</p>
    +  149   +
          * <code>
    +  150   +
          * cpe:/a:some-vendor:some-product:1.5.2
    +  151   +
          * </code>
    +  152   +
          *
    +  153   +
          * @param dependency the dependency being analyzed
    +  154   +
          */
    +  155   +
         @SuppressWarnings("null")
    +  156   +
         private void removeSpuriousCPE(Dependency dependency) {
    +  157  24
             final List<Identifier> ids = new ArrayList<Identifier>();
    +  158  24
             ids.addAll(dependency.getIdentifiers());
    +  159  24
             Collections.sort(ids);
    +  160  24
             final ListIterator<Identifier> mainItr = ids.listIterator();
    +  161  48
             while (mainItr.hasNext()) {
    +  162  24
                 final Identifier currentId = mainItr.next();
    +  163  24
                 final VulnerableSoftware currentCpe = parseCpe(currentId.getType(), currentId.getValue());
    +  164  24
                 if (currentCpe == null) {
    +  165  0
                     continue;
    +  166   +
                 }
    +  167  24
                 final ListIterator<Identifier> subItr = ids.listIterator(mainItr.nextIndex());
    +  168  48
                 while (subItr.hasNext()) {
    +  169  24
                     final Identifier nextId = subItr.next();
    +  170  24
                     final VulnerableSoftware nextCpe = parseCpe(nextId.getType(), nextId.getValue());
    +  171  24
                     if (nextCpe == null) {
    +  172  0
                         continue;
    +  173   +
                     }
    +  174   +
                     //TODO fix the version problem below
    +  175  24
                     if (currentCpe.getVendor().equals(nextCpe.getVendor())) {
    +  176  0
                         if (currentCpe.getProduct().equals(nextCpe.getProduct())) {
    +  177   +
                             // see if one is contained in the other.. remove the contained one from dependency.getIdentifier
    +  178  0
                             final String currentVersion = currentCpe.getVersion();
    +  179  0
                             final String nextVersion = nextCpe.getVersion();
    +  180  0
                             if (currentVersion == null && nextVersion == null) {
    +  181   +
                                 //how did we get here?
    +  182  0
                                 LOGGER.debug("currentVersion and nextVersion are both null?");
    +  183  0
                             } else if (currentVersion == null && nextVersion != null) {
    +  184  0
                                 dependency.getIdentifiers().remove(currentId);
    +  185  0
                             } else if (nextVersion == null && currentVersion != null) {
    +  186  0
                                 dependency.getIdentifiers().remove(nextId);
    +  187  0
                             } else if (currentVersion.length() < nextVersion.length()) {
    +  188  0
                                 if (nextVersion.startsWith(currentVersion) || "-".equals(currentVersion)) {
    +  189  0
                                     dependency.getIdentifiers().remove(currentId);
    +  190   +
                                 }
    +  191   +
                             } else {
    +  192  0
                                 if (currentVersion.startsWith(nextVersion) || "-".equals(nextVersion)) {
    +  193  0
                                     dependency.getIdentifiers().remove(nextId);
    +  194   +
                                 }
    +  195   +
                             }
    +  196   +
                         }
    +  197   +
                     }
    +  198  24
                 }
    +  199  24
             }
    +  200  24
         }
     201   -
          * Regex to identify core jsf libraries.
    -  202   -
          */
    -  203  1
         public static final Pattern CORE_JAVA_JSF = Pattern.compile("^cpe:/a:(sun|oracle|ibm):jsf($|:.*)");
    -  204  
         /**
    -  205   -
          * Regex to identify core java library files. This is currently incomplete.
    -  206   +  202   +
          * Regex to identify core java libraries and a few other commonly misidentified ones.
    +  203  
          */
    -  207  1
         public static final Pattern CORE_FILES = Pattern.compile("(^|/)((alt[-])?rt|jsse|jfxrt|jfr|jce|javaws|deploy|charsets)\\.jar$");
    +  204  8
         public static final Pattern CORE_JAVA = Pattern.compile("^cpe:/a:(sun|oracle|ibm):(j2[ems]e|"
    +  205   +
                 + "java(_platform_micro_edition|_runtime_environment|_se|virtual_machine|se_development_kit|fx)?|"
    +  206   +
                 + "jdk|jre|jsse)($|:.*)");
    +  207   +
     
     208  
         /**
     209   -
          * Regex to identify core jsf java library files. This is currently incomplete.
    +
          * Regex to identify core jsf libraries.
     210  
          */
    -  211  1
         public static final Pattern CORE_JSF_FILES = Pattern.compile("(^|/)jsf[-][^/]*\\.jar$");
    +  211  8
         public static final Pattern CORE_JAVA_JSF = Pattern.compile("^cpe:/a:(sun|oracle|ibm):jsf($|:.*)");
     212   -
     
    +
         /**
     213   -
         /**
    +
          * Regex to identify core java library files. This is currently incomplete.
     214   -
          * Removes any CPE entries for the JDK/JRE unless the filename ends with rt.jar
    -  215   -
          *
    +
          */
    +  215  8
         public static final Pattern CORE_FILES = Pattern.compile("(^|/)((alt[-])?rt|jsse|jfxrt|jfr|jce|javaws|deploy|charsets)\\.jar$");
     216   -
          * @param dependency the dependency to remove JRE CPEs from
    +
         /**
     217   -
          */
    +
          * Regex to identify core jsf java library files. This is currently incomplete.
     218   +
          */
    +  219  8
         public static final Pattern CORE_JSF_FILES = Pattern.compile("(^|/)jsf[-][^/]*\\.jar$");
    +  220   +
     
    +  221   +
         /**
    +  222   +
          * Removes any CPE entries for the JDK/JRE unless the filename ends with rt.jar
    +  223   +
          *
    +  224   +
          * @param dependency the dependency to remove JRE CPEs from
    +  225   +
          */
    +  226  
         private void removeJreEntries(Dependency dependency) {
    -  219  3
             final Set<Identifier> identifiers = dependency.getIdentifiers();
    -  220  3
             final Iterator<Identifier> itr = identifiers.iterator();
    -  221  6
             while (itr.hasNext()) {
    -  222  3
                 final Identifier i = itr.next();
    -  223  3
                 final Matcher coreCPE = CORE_JAVA.matcher(i.getValue());
    -  224  3
                 final Matcher coreFiles = CORE_FILES.matcher(dependency.getFileName());
    -  225  3
                 if (coreCPE.matches() && !coreFiles.matches()) {
    -  226  0
                     itr.remove();
    -  227   -
                 }
    -  228  3
                 final Matcher coreJsfCPE = CORE_JAVA_JSF.matcher(i.getValue());
    -  229  3
                 final Matcher coreJsfFiles = CORE_JSF_FILES.matcher(dependency.getFileName());
    -  230  3
                 if (coreJsfCPE.matches() && !coreJsfFiles.matches()) {
    -  231  0
                     itr.remove();
    -  232   -
                 }
    -  233  3
             }
    -  234  3
         }
    +  227  24
             final Set<Identifier> identifiers = dependency.getIdentifiers();
    +  228  24
             final Iterator<Identifier> itr = identifiers.iterator();
    +  229  56
             while (itr.hasNext()) {
    +  230  32
                 final Identifier i = itr.next();
    +  231  32
                 final Matcher coreCPE = CORE_JAVA.matcher(i.getValue());
    +  232  32
                 final Matcher coreFiles = CORE_FILES.matcher(dependency.getFileName());
    +  233  32
                 if (coreCPE.matches() && !coreFiles.matches()) {
    +  234  0
                     itr.remove();
     235   -
     
    -  236   -
         /**
    -  237   -
          * Parses a CPE string into an IndexEntry.
    -  238   -
          *
    -  239   -
          * @param type the type of identifier
    +
                 }
    +  236  32
                 final Matcher coreJsfCPE = CORE_JAVA_JSF.matcher(i.getValue());
    +  237  32
                 final Matcher coreJsfFiles = CORE_JSF_FILES.matcher(dependency.getFileName());
    +  238  32
                 if (coreJsfCPE.matches() && !coreJsfFiles.matches()) {
    +  239  0
                     itr.remove();
     240   -
          * @param value the cpe identifier to parse
    -  241   -
          * @return an VulnerableSoftware object constructed from the identifier
    -  242   -
          */
    +
                 }
    +  241  32
             }
    +  242  24
         }
     243   -
         private VulnerableSoftware parseCpe(String type, String value) {
    -  244  3
             if (!"cpe".equals(type)) {
    -  245  0
                 return null;
    +
     
    +  244   +
         /**
    +  245   +
          * Parses a CPE string into an IndexEntry.
     246   -
             }
    -  247  3
             final VulnerableSoftware cpe = new VulnerableSoftware();
    +
          *
    +  247   +
          * @param type the type of identifier
     248   -
             try {
    -  249  3
                 cpe.parseName(value);
    -  250  0
             } catch (UnsupportedEncodingException ex) {
    -  251  0
                 LOGGER.log(Level.FINEST, null, ex);
    -  252  0
                 return null;
    -  253  3
             }
    -  254  3
             return cpe;
    -  255   -
         }
    +
          * @param value the cpe identifier to parse
    +  249   +
          * @return an VulnerableSoftware object constructed from the identifier
    +  250   +
          */
    +  251   +
         private VulnerableSoftware parseCpe(String type, String value) {
    +  252  48
             if (!"cpe".equals(type)) {
    +  253  0
                 return null;
    +  254   +
             }
    +  255  48
             final VulnerableSoftware cpe = new VulnerableSoftware();
     256   -
     
    -  257   -
         /**
    -  258   -
          * Removes bad CPE matches for a dependency. Unfortunately, right now these are hard-coded patches for specific
    -  259   -
          * problems identified when testing this on a LARGE volume of jar files.
    -  260   -
          *
    -  261   -
          * @param dependency the dependency to analyze
    -  262   -
          */
    +
             try {
    +  257  48
                 cpe.parseName(value);
    +  258  0
             } catch (UnsupportedEncodingException ex) {
    +  259  0
                 LOGGER.trace("", ex);
    +  260  0
                 return null;
    +  261  48
             }
    +  262  48
             return cpe;
     263   -
         private void removeBadMatches(Dependency dependency) {
    -  264  3
             final Set<Identifier> identifiers = dependency.getIdentifiers();
    -  265  3
             final Iterator<Identifier> itr = identifiers.iterator();
    +
         }
    +  264   +
     
    +  265   +
         /**
     266   -
     
    +
          * Removes bad CPE matches for a dependency. Unfortunately, right now these are hard-coded patches for specific problems
     267   -
             /* TODO - can we utilize the pom's groupid and artifactId to filter??? most of
    +
          * identified when testing this on a LARGE volume of jar files.
     268   -
              * these are due to low quality data.  Other idea would be to say any CPE
    +
          *
     269   -
              * found based on LOW confidence evidence should have a different CPE type? (this
    -  270   -
              * might be a better solution then just removing the URL for "best-guess" matches).
    -  271   -
              */
    -  272   -
             //Set<Evidence> groupId = dependency.getVendorEvidence().getEvidence("pom", "groupid");
    -  273   -
             //Set<Evidence> artifactId = dependency.getVendorEvidence().getEvidence("pom", "artifactid");
    -  274  6
             while (itr.hasNext()) {
    -  275  3
                 final Identifier i = itr.next();
    -  276   -
                 //TODO move this startsWith expression to a configuration file?
    -  277  3
                 if ("cpe".equals(i.getType())) {
    -  278  3
                     if ((i.getValue().matches(".*c\\+\\+.*")
    -  279   -
                             || i.getValue().startsWith("cpe:/a:file:file")
    -  280   -
                             || i.getValue().startsWith("cpe:/a:mozilla:mozilla")
    -  281   -
                             || i.getValue().startsWith("cpe:/a:cvs:cvs")
    -  282   -
                             || i.getValue().startsWith("cpe:/a:ftp:ftp")
    -  283   -
                             || i.getValue().startsWith("cpe:/a:tcp:tcp")
    -  284   -
                             || i.getValue().startsWith("cpe:/a:ssh:ssh")
    -  285   -
                             || i.getValue().startsWith("cpe:/a:lookup:lookup"))
    -  286   -
                             && (dependency.getFileName().toLowerCase().endsWith(".jar")
    -  287   -
                             || dependency.getFileName().toLowerCase().endsWith("pom.xml")
    -  288   -
                             || dependency.getFileName().toLowerCase().endsWith(".dll")
    -  289   -
                             || dependency.getFileName().toLowerCase().endsWith(".exe")
    -  290   -
                             || dependency.getFileName().toLowerCase().endsWith(".nuspec")
    -  291   -
                             || dependency.getFileName().toLowerCase().endsWith(".nupkg"))) {
    -  292  1
                         itr.remove();
    -  293  2
                     } else if ((i.getValue().startsWith("cpe:/a:jquery:jquery")
    -  294   -
                             || i.getValue().startsWith("cpe:/a:prototypejs:prototype")
    -  295   -
                             || i.getValue().startsWith("cpe:/a:yahoo:yui"))
    -  296   -
                             && (dependency.getFileName().toLowerCase().endsWith(".jar")
    -  297   -
                             || dependency.getFileName().toLowerCase().endsWith("pom.xml")
    -  298   -
                             || dependency.getFileName().toLowerCase().endsWith(".dll")
    -  299   -
                             || dependency.getFileName().toLowerCase().endsWith(".exe"))) {
    -  300  0
                         itr.remove();
    -  301  2
                     } else if ((i.getValue().startsWith("cpe:/a:microsoft:excel")
    -  302   -
                             || i.getValue().startsWith("cpe:/a:microsoft:word")
    -  303   -
                             || i.getValue().startsWith("cpe:/a:microsoft:visio")
    -  304   -
                             || i.getValue().startsWith("cpe:/a:microsoft:powerpoint")
    -  305   -
                             || i.getValue().startsWith("cpe:/a:microsoft:office"))
    -  306   -
                             && (dependency.getFileName().toLowerCase().endsWith(".jar")
    -  307   -
                             || dependency.getFileName().toLowerCase().endsWith("pom.xml"))) {
    -  308  0
                         itr.remove();
    -  309  2
                     } else if (i.getValue().startsWith("cpe:/a:apache:maven")
    -  310   -
                             && !dependency.getFileName().toLowerCase().matches("maven-core-[\\d\\.]+\\.jar")) {
    -  311  0
                         itr.remove();
    -  312  2
                     } else if (i.getValue().startsWith("cpe:/a:m-core:m-core")
    -  313   -
                             && !dependency.getEvidenceUsed().containsUsedString("m-core")) {
    -  314  0
                         itr.remove();
    -  315  2
                     } else if (i.getValue().startsWith("cpe:/a:jboss:jboss")
    -  316   -
                             && !dependency.getFileName().toLowerCase().matches("jboss-?[\\d\\.-]+(GA)?\\.jar")) {
    -  317  0
                         itr.remove();
    -  318   -
                     }
    -  319   -
                 }
    -  320  3
             }
    -  321  3
         }
    -  322   -
     
    -  323   -
         /**
    -  324   -
          * Removes CPE matches for the wrong version of a dependency. Currently, this only covers Axis 1 & 2.
    -  325   -
          *
    -  326  
          * @param dependency the dependency to analyze
    -  327   +  270  
          */
    +  271   +
         private void removeBadMatches(Dependency dependency) {
    +  272  24
             final Set<Identifier> identifiers = dependency.getIdentifiers();
    +  273  24
             final Iterator<Identifier> itr = identifiers.iterator();
    +  274   +
     
    +  275   +
             /* TODO - can we utilize the pom's groupid and artifactId to filter??? most of
    +  276   +
              * these are due to low quality data.  Other idea would be to say any CPE
    +  277   +
              * found based on LOW confidence evidence should have a different CPE type? (this
    +  278   +
              * might be a better solution then just removing the URL for "best-guess" matches).
    +  279   +
              */
    +  280   +
             //Set<Evidence> groupId = dependency.getVendorEvidence().getEvidence("pom", "groupid");
    +  281   +
             //Set<Evidence> artifactId = dependency.getVendorEvidence().getEvidence("pom", "artifactid");
    +  282  56
             while (itr.hasNext()) {
    +  283  32
                 final Identifier i = itr.next();
    +  284   +
                 //TODO move this startsWith expression to the base suppression file
    +  285  32
                 if ("cpe".equals(i.getType())) {
    +  286  32
                     if ((i.getValue().matches(".*c\\+\\+.*")
    +  287   +
                             || i.getValue().startsWith("cpe:/a:file:file")
    +  288   +
                             || i.getValue().startsWith("cpe:/a:mozilla:mozilla")
    +  289   +
                             || i.getValue().startsWith("cpe:/a:cvs:cvs")
    +  290   +
                             || i.getValue().startsWith("cpe:/a:ftp:ftp")
    +  291   +
                             || i.getValue().startsWith("cpe:/a:tcp:tcp")
    +  292   +
                             || i.getValue().startsWith("cpe:/a:ssh:ssh")
    +  293   +
                             || i.getValue().startsWith("cpe:/a:lookup:lookup"))
    +  294   +
                             && (dependency.getFileName().toLowerCase().endsWith(".jar")
    +  295   +
                             || dependency.getFileName().toLowerCase().endsWith("pom.xml")
    +  296   +
                             || dependency.getFileName().toLowerCase().endsWith(".dll")
    +  297   +
                             || dependency.getFileName().toLowerCase().endsWith(".exe")
    +  298   +
                             || dependency.getFileName().toLowerCase().endsWith(".nuspec")
    +  299   +
                             || dependency.getFileName().toLowerCase().endsWith(".zip")
    +  300   +
                             || dependency.getFileName().toLowerCase().endsWith(".sar")
    +  301   +
                             || dependency.getFileName().toLowerCase().endsWith(".apk")
    +  302   +
                             || dependency.getFileName().toLowerCase().endsWith(".tar")
    +  303   +
                             || dependency.getFileName().toLowerCase().endsWith(".gz")
    +  304   +
                             || dependency.getFileName().toLowerCase().endsWith(".tgz")
    +  305   +
                             || dependency.getFileName().toLowerCase().endsWith(".ear")
    +  306   +
                             || dependency.getFileName().toLowerCase().endsWith(".war"))) {
    +  307  8
                         itr.remove();
    +  308  24
                     } else if ((i.getValue().startsWith("cpe:/a:jquery:jquery")
    +  309   +
                             || i.getValue().startsWith("cpe:/a:prototypejs:prototype")
    +  310   +
                             || i.getValue().startsWith("cpe:/a:yahoo:yui"))
    +  311   +
                             && (dependency.getFileName().toLowerCase().endsWith(".jar")
    +  312   +
                             || dependency.getFileName().toLowerCase().endsWith("pom.xml")
    +  313   +
                             || dependency.getFileName().toLowerCase().endsWith(".dll")
    +  314   +
                             || dependency.getFileName().toLowerCase().endsWith(".exe"))) {
    +  315  0
                         itr.remove();
    +  316  24
                     } else if ((i.getValue().startsWith("cpe:/a:microsoft:excel")
    +  317   +
                             || i.getValue().startsWith("cpe:/a:microsoft:word")
    +  318   +
                             || i.getValue().startsWith("cpe:/a:microsoft:visio")
    +  319   +
                             || i.getValue().startsWith("cpe:/a:microsoft:powerpoint")
    +  320   +
                             || i.getValue().startsWith("cpe:/a:microsoft:office")
    +  321   +
                             || i.getValue().startsWith("cpe:/a:core_ftp:core_ftp"))
    +  322   +
                             && (dependency.getFileName().toLowerCase().endsWith(".jar")
    +  323   +
                             || dependency.getFileName().toLowerCase().endsWith(".ear")
    +  324   +
                             || dependency.getFileName().toLowerCase().endsWith(".war")
    +  325   +
                             || dependency.getFileName().toLowerCase().endsWith("pom.xml"))) {
    +  326  0
                         itr.remove();
    +  327  24
                     } else if (i.getValue().startsWith("cpe:/a:apache:maven")
     328   -
         private void removeWrongVersionMatches(Dependency dependency) {
    -  329  3
             final Set<Identifier> identifiers = dependency.getIdentifiers();
    -  330  3
             final Iterator<Identifier> itr = identifiers.iterator();
    +
                             && !dependency.getFileName().toLowerCase().matches("maven-core-[\\d\\.]+\\.jar")) {
    +  329  0
                         itr.remove();
    +  330  24
                     } else if (i.getValue().startsWith("cpe:/a:m-core:m-core")
     331   -
     
    -  332  3
             final String fileName = dependency.getFileName();
    -  333  3
             if (fileName != null && fileName.contains("axis2")) {
    -  334  0
                 while (itr.hasNext()) {
    -  335  0
                     final Identifier i = itr.next();
    -  336  0
                     if ("cpe".equals(i.getType())) {
    -  337  0
                         final String cpe = i.getValue();
    -  338  0
                         if (cpe != null && (cpe.startsWith("cpe:/a:apache:axis:") || "cpe:/a:apache:axis".equals(cpe))) {
    -  339  0
                             itr.remove();
    +
                             && !dependency.getEvidenceUsed().containsUsedString("m-core")) {
    +  332  0
                         itr.remove();
    +  333  24
                     } else if (i.getValue().startsWith("cpe:/a:jboss:jboss")
    +  334   +
                             && !dependency.getFileName().toLowerCase().matches("jboss-?[\\d\\.-]+(GA)?\\.jar")) {
    +  335  0
                         itr.remove();
    +  336   +
                     }
    +  337   +
                 }
    +  338  32
             }
    +  339  24
         }
     340   -
                         }
    +
     
     341   -
                     }
    -  342  0
                 }
    -  343  3
             } else if (fileName != null && fileName.contains("axis")) {
    -  344  0
                 while (itr.hasNext()) {
    -  345  0
                     final Identifier i = itr.next();
    -  346  0
                     if ("cpe".equals(i.getType())) {
    -  347  0
                         final String cpe = i.getValue();
    -  348  0
                         if (cpe != null && (cpe.startsWith("cpe:/a:apache:axis2:") || "cpe:/a:apache:axis2".equals(cpe))) {
    -  349  0
                             itr.remove();
    -  350   -
                         }
    -  351   -
                     }
    -  352  0
                 }
    -  353   -
             }
    -  354  3
         }
    -  355   -
     
    -  356  
         /**
    -  357   -
          * There are some known CPE entries, specifically regarding sun and oracle products due to the acquisition and
    +  342   +
          * Removes CPE matches for the wrong version of a dependency. Currently, this only covers Axis 1 & 2.
    +  343   +
          *
    +  344   +
          * @param dependency the dependency to analyze
    +  345   +
          */
    +  346   +
         private void removeWrongVersionMatches(Dependency dependency) {
    +  347  24
             final Set<Identifier> identifiers = dependency.getIdentifiers();
    +  348  24
             final Iterator<Identifier> itr = identifiers.iterator();
    +  349   +
     
    +  350  24
             final String fileName = dependency.getFileName();
    +  351  24
             if (fileName != null && fileName.contains("axis2")) {
    +  352  0
                 while (itr.hasNext()) {
    +  353  0
                     final Identifier i = itr.next();
    +  354  0
                     if ("cpe".equals(i.getType())) {
    +  355  0
                         final String cpe = i.getValue();
    +  356  0
                         if (cpe != null && (cpe.startsWith("cpe:/a:apache:axis:") || "cpe:/a:apache:axis".equals(cpe))) {
    +  357  0
                             itr.remove();
     358   -
          * changes in product names, that based on given evidence we can add the related CPE entries to ensure a complete
    -  359   -
          * list of CVE entries.
    -  360   -
          *
    -  361   -
          * @param dependency the dependency being analyzed
    -  362   -
          */
    -  363   -
         private void addFalseNegativeCPEs(Dependency dependency) {
    -  364   -
             //TODO move this to the hint analyzer
    -  365  3
             final Iterator<Identifier> itr = dependency.getIdentifiers().iterator();
    -  366  5
             while (itr.hasNext()) {
    -  367  2
                 final Identifier i = itr.next();
    -  368  2
                 if ("cpe".equals(i.getType()) && i.getValue() != null
    -  369   -
                         && (i.getValue().startsWith("cpe:/a:oracle:opensso:")
    -  370   -
                         || i.getValue().startsWith("cpe:/a:oracle:opensso_enterprise:")
    -  371   -
                         || i.getValue().startsWith("cpe:/a:sun:opensso_enterprise:")
    -  372   -
                         || i.getValue().startsWith("cpe:/a:sun:opensso:"))) {
    -  373  0
                     final String newCpe = String.format("cpe:/a:sun:opensso_enterprise:%s", i.getValue().substring(22));
    -  374  0
                     final String newCpe2 = String.format("cpe:/a:oracle:opensso_enterprise:%s", i.getValue().substring(22));
    -  375  0
                     final String newCpe3 = String.format("cpe:/a:sun:opensso:%s", i.getValue().substring(22));
    -  376  0
                     final String newCpe4 = String.format("cpe:/a:oracle:opensso:%s", i.getValue().substring(22));
    -  377   -
                     try {
    -  378  0
                         dependency.addIdentifier("cpe",
    -  379   -
                                 newCpe,
    -  380   -
                                 String.format(CPEAnalyzer.NVD_SEARCH_URL, URLEncoder.encode(newCpe, "UTF-8")));
    -  381  0
                         dependency.addIdentifier("cpe",
    -  382   -
                                 newCpe2,
    -  383   -
                                 String.format(CPEAnalyzer.NVD_SEARCH_URL, URLEncoder.encode(newCpe2, "UTF-8")));
    -  384  0
                         dependency.addIdentifier("cpe",
    -  385   -
                                 newCpe3,
    -  386   -
                                 String.format(CPEAnalyzer.NVD_SEARCH_URL, URLEncoder.encode(newCpe3, "UTF-8")));
    -  387  0
                         dependency.addIdentifier("cpe",
    -  388   -
                                 newCpe4,
    -  389   -
                                 String.format(CPEAnalyzer.NVD_SEARCH_URL, URLEncoder.encode(newCpe4, "UTF-8")));
    -  390  0
                     } catch (UnsupportedEncodingException ex) {
    -  391  0
                         LOGGER.log(Level.FINE, null, ex);
    -  392  0
                     }
    -  393   -
                 }
    -  394  2
             }
    -  395  3
         }
    -  396   -
     
    -  397   -
         /**
    -  398   -
          * Removes duplicate entries identified that are contained within JAR files. These occasionally crop up due to POM
    -  399   -
          * entries or other types of files (such as DLLs and EXEs) being contained within the JAR.
    -  400   -
          *
    -  401   -
          * @param dependency the dependency that might be a duplicate
    -  402   -
          * @param engine the engine used to scan all dependencies
    -  403   -
          */
    -  404   -
         private void removeDuplicativeEntriesFromJar(Dependency dependency, Engine engine) {
    -  405  3
             if (dependency.getFileName().toLowerCase().endsWith("pom.xml")
    -  406   -
                     || "dll".equals(dependency.getFileExtension())
    -  407   -
                     || "exe".equals(dependency.getFileExtension())) {
    -  408  1
                 String parentPath = dependency.getFilePath().toLowerCase();
    -  409  1
                 if (parentPath.contains(".jar")) {
    -  410  0
                     parentPath = parentPath.substring(0, parentPath.indexOf(".jar") + 4);
    -  411  0
                     final Dependency parent = findDependency(parentPath, engine.getDependencies());
    -  412  0
                     if (parent != null) {
    -  413  0
                         boolean remove = false;
    -  414  0
                         for (Identifier i : dependency.getIdentifiers()) {
    -  415  0
                             if ("cpe".equals(i.getType())) {
    -  416  0
                                 final String trimmedCPE = trimCpeToVendor(i.getValue());
    -  417  0
                                 for (Identifier parentId : parent.getIdentifiers()) {
    -  418  0
                                     if ("cpe".equals(parentId.getType()) && parentId.getValue().startsWith(trimmedCPE)) {
    -  419  0
                                         remove |= true;
    -  420   -
                                     }
    -  421  0
                                 }
    -  422   -
                             }
    -  423  0
                             if (!remove) { //we can escape early
    -  424  0
                                 return;
    -  425   -
                             }
    -  426  0
                         }
    -  427  0
                         if (remove) {
    -  428  0
                             engine.getDependencies().remove(dependency);
    -  429  
                         }
    -  430   +  359  
                     }
    -  431   -
                 }
    -  432   -
     
    -  433   +  360  0
                 }
    +  361  24
             } else if (fileName != null && fileName.contains("axis")) {
    +  362  0
                 while (itr.hasNext()) {
    +  363  0
                     final Identifier i = itr.next();
    +  364  0
                     if ("cpe".equals(i.getType())) {
    +  365  0
                         final String cpe = i.getValue();
    +  366  0
                         if (cpe != null && (cpe.startsWith("cpe:/a:apache:axis2:") || "cpe:/a:apache:axis2".equals(cpe))) {
    +  367  0
                             itr.remove();
    +  368   +
                         }
    +  369   +
                     }
    +  370  0
                 }
    +  371  
             }
    -  434  3
         }
    -  435   +  372  24
         }
    +  373  
     
    -  436   +  374  
         /**
    -  437   -
          * Retrieves a given dependency, based on a given path, from a list of dependencies.
    -  438   +  375   +
          * There are some known CPE entries, specifically regarding sun and oracle products due to the acquisition and changes in
    +  376   +
          * product names, that based on given evidence we can add the related CPE entries to ensure a complete list of CVE entries.
    +  377  
          *
    -  439   -
          * @param dependencyPath the path of the dependency to return
    -  440   -
          * @param dependencies the collection of dependencies to search
    -  441   -
          * @return the dependency object for the given path, otherwise null
    -  442   +  378   +
          * @param dependency the dependency being analyzed
    +  379  
          */
    -  443   -
         private Dependency findDependency(String dependencyPath, List<Dependency> dependencies) {
    -  444  0
             for (Dependency d : dependencies) {
    -  445  0
                 if (d.getFilePath().equalsIgnoreCase(dependencyPath)) {
    -  446  0
                     return d;
    +  380   +
         private void addFalseNegativeCPEs(Dependency dependency) {
    +  381   +
             //TODO move this to the hint analyzer
    +  382  24
             final Iterator<Identifier> itr = dependency.getIdentifiers().iterator();
    +  383  48
             while (itr.hasNext()) {
    +  384  24
                 final Identifier i = itr.next();
    +  385  24
                 if ("cpe".equals(i.getType()) && i.getValue() != null
    +  386   +
                         && (i.getValue().startsWith("cpe:/a:oracle:opensso:")
    +  387   +
                         || i.getValue().startsWith("cpe:/a:oracle:opensso_enterprise:")
    +  388   +
                         || i.getValue().startsWith("cpe:/a:sun:opensso_enterprise:")
    +  389   +
                         || i.getValue().startsWith("cpe:/a:sun:opensso:"))) {
    +  390  0
                     final String newCpe = String.format("cpe:/a:sun:opensso_enterprise:%s", i.getValue().substring(22));
    +  391  0
                     final String newCpe2 = String.format("cpe:/a:oracle:opensso_enterprise:%s", i.getValue().substring(22));
    +  392  0
                     final String newCpe3 = String.format("cpe:/a:sun:opensso:%s", i.getValue().substring(22));
    +  393  0
                     final String newCpe4 = String.format("cpe:/a:oracle:opensso:%s", i.getValue().substring(22));
    +  394   +
                     try {
    +  395  0
                         dependency.addIdentifier("cpe",
    +  396   +
                                 newCpe,
    +  397   +
                                 String.format(CPEAnalyzer.NVD_SEARCH_URL, URLEncoder.encode(newCpe, "UTF-8")));
    +  398  0
                         dependency.addIdentifier("cpe",
    +  399   +
                                 newCpe2,
    +  400   +
                                 String.format(CPEAnalyzer.NVD_SEARCH_URL, URLEncoder.encode(newCpe2, "UTF-8")));
    +  401  0
                         dependency.addIdentifier("cpe",
    +  402   +
                                 newCpe3,
    +  403   +
                                 String.format(CPEAnalyzer.NVD_SEARCH_URL, URLEncoder.encode(newCpe3, "UTF-8")));
    +  404  0
                         dependency.addIdentifier("cpe",
    +  405   +
                                 newCpe4,
    +  406   +
                                 String.format(CPEAnalyzer.NVD_SEARCH_URL, URLEncoder.encode(newCpe4, "UTF-8")));
    +  407  0
                     } catch (UnsupportedEncodingException ex) {
    +  408  0
                         LOGGER.debug("", ex);
    +  409  0
                     }
    +  410   +
                 }
    +  411  24
             }
    +  412  24
         }
    +  413   +
     
    +  414   +
         /**
    +  415   +
          * Removes duplicate entries identified that are contained within JAR files. These occasionally crop up due to POM entries or
    +  416   +
          * other types of files (such as DLLs and EXEs) being contained within the JAR.
    +  417   +
          *
    +  418   +
          * @param dependency the dependency that might be a duplicate
    +  419   +
          * @param engine the engine used to scan all dependencies
    +  420   +
          */
    +  421   +
         private void removeDuplicativeEntriesFromJar(Dependency dependency, Engine engine) {
    +  422  24
             if (dependency.getFileName().toLowerCase().endsWith("pom.xml")
    +  423   +
                     || DLL_EXE_FILTER.accept(dependency.getActualFile())) {
    +  424  8
                 String parentPath = dependency.getFilePath().toLowerCase();
    +  425  8
                 if (parentPath.contains(".jar")) {
    +  426  0
                     parentPath = parentPath.substring(0, parentPath.indexOf(".jar") + 4);
    +  427  0
                     final Dependency parent = findDependency(parentPath, engine.getDependencies());
    +  428  0
                     if (parent != null) {
    +  429  0
                         boolean remove = false;
    +  430  0
                         for (Identifier i : dependency.getIdentifiers()) {
    +  431  0
                             if ("cpe".equals(i.getType())) {
    +  432  0
                                 final String trimmedCPE = trimCpeToVendor(i.getValue());
    +  433  0
                                 for (Identifier parentId : parent.getIdentifiers()) {
    +  434  0
                                     if ("cpe".equals(parentId.getType()) && parentId.getValue().startsWith(trimmedCPE)) {
    +  435  0
                                         remove |= true;
    +  436   +
                                     }
    +  437  0
                                 }
    +  438   +
                             }
    +  439  0
                             if (!remove) { //we can escape early
    +  440  0
                                 return;
    +  441   +
                             }
    +  442  0
                         }
    +  443  0
                         if (remove) {
    +  444  0
                             engine.getDependencies().remove(dependency);
    +  445   +
                         }
    +  446   +
                     }
     447  
                 }
    -  448  0
             }
    -  449  0
             return null;
    -  450   -
         }
    +  448   +
     
    +  449   +
             }
    +  450  24
         }
     451  
     
     452  
         /**
     453   -
          * Takes a full CPE and returns the CPE trimmed to include only vendor and product.
    +
          * Retrieves a given dependency, based on a given path, from a list of dependencies.
     454  
          *
     455   -
          * @param value the CPE value to trim
    +
          * @param dependencyPath the path of the dependency to return
     456   -
          * @return a CPE value that only includes the vendor and product
    +
          * @param dependencies the collection of dependencies to search
     457   -
          */
    +
          * @return the dependency object for the given path, otherwise null
     458   -
         private String trimCpeToVendor(String value) {
    +
          */
     459   -
             //cpe:/a:jruby:jruby:1.0.8
    -  460  0
             final int pos1 = value.indexOf(":", 7); //right of vendor
    -  461  0
             final int pos2 = value.indexOf(":", pos1 + 1); //right of product
    -  462  0
             if (pos2 < 0) {
    -  463  0
                 return value;
    -  464   -
             } else {
    -  465  0
                 return value.substring(0, pos2);
    +
         private Dependency findDependency(String dependencyPath, List<Dependency> dependencies) {
    +  460  0
             for (Dependency d : dependencies) {
    +  461  0
                 if (d.getFilePath().equalsIgnoreCase(dependencyPath)) {
    +  462  0
                     return d;
    +  463   +
                 }
    +  464  0
             }
    +  465  0
             return null;
     466   -
             }
    -  467  
         }
    +  467   +
     
     468   +
         /**
    +  469   +
          * Takes a full CPE and returns the CPE trimmed to include only vendor and product.
    +  470   +
          *
    +  471   +
          * @param value the CPE value to trim
    +  472   +
          * @return a CPE value that only includes the vendor and product
    +  473   +
          */
    +  474   +
         private String trimCpeToVendor(String value) {
    +  475   +
             //cpe:/a:jruby:jruby:1.0.8
    +  476  0
             final int pos1 = value.indexOf(":", 7); //right of vendor
    +  477  0
             final int pos2 = value.indexOf(":", pos1 + 1); //right of product
    +  478  0
             if (pos2 < 0) {
    +  479  0
                 return value;
    +  480   +
             } else {
    +  481  0
                 return value.substring(0, pos2);
    +  482   +
             }
    +  483   +
         }
    +  484  
     }
    - + 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 0c4abc2f7..02f410190 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.FileNameAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.FileNameAnalyzer.html @@ -83,7 +83,7 @@
      * @author Jeremy Long
     33  
      */
    -  34  7
     public class FileNameAnalyzer extends AbstractAnalyzer implements Analyzer {
    +  34  64
     public class FileNameAnalyzer 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.INFORMATION_COLLECTION;
    +  44  8
         private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
     45  
     
     46   @@ -117,7 +117,7 @@
          */
     51  
         public String getName() {
    -  52  5
             return ANALYZER_NAME;
    +  52  40
             return ANALYZER_NAME;
     53  
         }
     54   @@ -134,7 +134,7 @@
          */
     60  
         public AnalysisPhase getAnalysisPhase() {
    -  61  2
             return ANALYSIS_PHASE;
    +  61  24
             return ANALYSIS_PHASE;
     62  
         }
     63   @@ -163,41 +163,41 @@
     
     75  
             //strip any path information that may get added by ArchiveAnalyzer, etc.
    -  76  4
             final File f = dependency.getActualFile();
    -  77  4
             String fileName = f.getName();
    +  76  32
             final File f = dependency.getActualFile();
    +  77  32
             String fileName = f.getName();
     78  
     
     79  
             //remove file extension
    -  80  4
             final int pos = fileName.lastIndexOf(".");
    -  81  4
             if (pos > 0) {
    -  82  4
                 fileName = fileName.substring(0, pos);
    +  80  32
             final int pos = fileName.lastIndexOf(".");
    +  81  32
             if (pos > 0) {
    +  82  32
                 fileName = fileName.substring(0, pos);
     83  
             }
     84  
     
     85  
             //add version evidence
    -  86  4
             final DependencyVersion version = DependencyVersionUtil.parseVersion(fileName);
    -  87  4
             if (version != null) {
    +  86  32
             final DependencyVersion version = DependencyVersionUtil.parseVersion(fileName);
    +  87  32
             if (version != null) {
     88  
                 // If the version number is just a number like 2 or 23, reduce the confidence
     89  
                 // a shade. This should hopefully correct for cases like log4j.jar or
     90  
                 // struts2-core.jar
    -  91  4
                 if (version.getVersionParts() == null || version.getVersionParts().size() < 2) {
    +  91  32
                 if (version.getVersionParts() == null || version.getVersionParts().size() < 2) {
     92  0
                     dependency.getVersionEvidence().addEvidence("file", "name",
     93  
                             version.toString(), Confidence.MEDIUM);
     94  
                 } else {
    -  95  4
                     dependency.getVersionEvidence().addEvidence("file", "name",
    +  95  32
                     dependency.getVersionEvidence().addEvidence("file", "name",
     96  
                             version.toString(), Confidence.HIGHEST);
     97  
                 }
    -  98  4
                 dependency.getVersionEvidence().addEvidence("file", "name",
    +  98  32
                 dependency.getVersionEvidence().addEvidence("file", "name",
     99  
                         fileName, Confidence.MEDIUM);
     100   @@ -206,11 +206,11 @@
     
     102  
             //add as vendor and product evidence
    -  103  4
             if (fileName.contains("-")) {
    -  104  4
                 dependency.getProductEvidence().addEvidence("file", "name",
    +  103  32
             if (fileName.contains("-")) {
    +  104  32
                 dependency.getProductEvidence().addEvidence("file", "name",
     105  
                         fileName, Confidence.HIGHEST);
    -  106  4
                 dependency.getVendorEvidence().addEvidence("file", "name",
    +  106  32
                 dependency.getVendorEvidence().addEvidence("file", "name",
     107  
                         fileName, Confidence.HIGHEST);
     108   @@ -223,11 +223,11 @@
                         fileName, Confidence.HIGH);
     113  
             }
    -  114  4
         }
    +  114  32
         }
     115  
     }
    - + 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 d5fd6a040..1f14dae47 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.FileTypeAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.FileTypeAnalyzer.html @@ -56,47 +56,35 @@  19  
     
     20   -
     /**
    +
     import java.io.FileFilter;
     21   -
      * An Analyzer that scans specific file types.
    +
     
     22   -
      *
    +
     /**
     23   -
      * @author Jeremy Long
    +
      * An Analyzer that scans specific file types.
     24   -
      */
    +
      *
     25   -
     public interface FileTypeAnalyzer extends Analyzer {
    +
      * @author Jeremy Long
     26   -
     
    +
      */
     27   -
         /**
    +
     public interface FileTypeAnalyzer extends Analyzer, FileFilter {
     28   -
          * Returns whether or not this analyzer can process the given extension.
    -  29   -
          *
    -  30   -
          * @param extension the file extension to test for support.
    -  31   -
          * @return whether or not the specified file extension is supported by this analyzer.
    -  32   -
          */
    -  33   -
         boolean supportsExtension(String extension);
    -  34  
     
    -  35   +  29  
         /**
    -  36   +  30  
          * Resets the analyzers state.
    -  37   +  31  
          */
    -  38   +  32  
         void reset();
    -  39   +  33  
     }
    - + 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 44c518b7d..60b513eca 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.HintAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.HintAnalyzer.html @@ -12,7 +12,7 @@
     
    - +
    Classes in this File Line Coverage Branch Coverage Complexity
    HintAnalyzer
    78%
    26/33
    54%
    12/22
    4.667
    HintAnalyzer
    75%
    30/40
    58%
    14/24
    5
     
    @@ -83,7 +83,7 @@
      * @author Jeremy Long
     33  
      */
    -  34  5
     public class HintAnalyzer extends AbstractAnalyzer implements Analyzer {
    +  34  48
     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  8
         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  40
             return ANALYZER_NAME;
     54  
         }
     55   @@ -138,7 +138,7 @@
         @Override
     62  
         public AnalysisPhase getAnalysisPhase() {
    -  63  2
             return ANALYSIS_PHASE;
    +  63  24
             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  16
             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  16
             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  16
             final Evidence springTest3 = new Evidence("Manifest",
     88  
                     "Implementation-Title",
     89   @@ -192,72 +192,91 @@
                     Confidence.HIGH);
     91  
     
    -  92  2
             final Evidence springTest4 = new Evidence("Manifest",
    +  92  16
             final Evidence springTest4 = new Evidence("jar",
     93   -
                     "Bundle-Vendor",
    +
                     "package name",
     94   -
                     "SpringSource",
    +
                     "springframework",
     95   -
                     Confidence.HIGH);
    +
                     Confidence.LOW);
     96  
     
    -  97  2
             final Evidence springTest5 = new Evidence("jar",
    +  97  16
             final Evidence springSecurityTest1 = new Evidence("Manifest",
     98   -
                     "package name",
    +
                     "Bundle-Name",
     99   -
                     "springframework",
    +
                     "Spring Security Core",
     100   -
                     Confidence.LOW);
    +
                     Confidence.MEDIUM);
     101  
     
    -  102   -
             //springsource/vware problem
    -  103  2
             final Set<Evidence> product = dependency.getProductEvidence().getEvidence();
    -  104  2
             final Set<Evidence> vendor = dependency.getVendorEvidence().getEvidence();
    +  102  16
             final Evidence springSecurityTest2 = new Evidence("pom",
    +  103   +
                     "artifactid",
    +  104   +
                     "spring-security-core",
     105   +
                     Confidence.HIGH);
    +  106  
     
    -  106  2
             if (product.contains(springTest1) || product.contains(springTest2) || product.contains(springTest3)
     107   -
                     || (dependency.getFileName().contains("spring") && (product.contains(springTest5) || vendor.contains(springTest5)))) {
    -  108  1
                 dependency.getProductEvidence().addEvidence("hint analyzer", "product", "springsource spring framework", Confidence.HIGH);
    -  109  1
                 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "SpringSource", Confidence.HIGH);
    -  110  1
                 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "vmware", Confidence.HIGH);
    -  111   -
             }
    +
             //springsource/vware problem
    +  108  16
             final Set<Evidence> product = dependency.getProductEvidence().getEvidence();
    +  109  16
             final Set<Evidence> vendor = dependency.getVendorEvidence().getEvidence();
    +  110   +
     
    +  111  16
             if (product.contains(springTest1) || product.contains(springTest2) || product.contains(springTest3)
     112   -
     
    -  113  2
             if (vendor.contains(springTest4)) {
    -  114  1
                 dependency.getProductEvidence().addEvidence("hint analyzer", "product", "springsource_spring_framework", Confidence.HIGH);
    -  115  1
                 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "vmware", Confidence.HIGH);
    -  116   -
             }
    +
                     || (dependency.getFileName().contains("spring") && product.contains(springTest4))) {
    +  113  8
                 dependency.getProductEvidence().addEvidence("hint analyzer", "product", "springsource spring framework", Confidence.HIGH);
    +  114  8
                 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "SpringSource", Confidence.HIGH);
    +  115  8
                 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "vmware", Confidence.HIGH);
    +  116  8
                 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "pivotal", Confidence.HIGH);
     117   -
     
    +
             }
     118   -
             //sun/oracle problem
    -  119  2
             final Iterator<Evidence> itr = dependency.getVendorEvidence().iterator();
    -  120  2
             final List<Evidence> newEntries = new ArrayList<Evidence>();
    -  121  28
             while (itr.hasNext()) {
    -  122  26
                 final Evidence e = itr.next();
    -  123  26
                 if ("sun".equalsIgnoreCase(e.getValue(false))) {
    -  124  0
                     final Evidence newEvidence = new Evidence(e.getSource() + " (hint)", e.getName(), "oracle", e.getConfidence());
    -  125  0
                     newEntries.add(newEvidence);
    -  126  0
                 } else if ("oracle".equalsIgnoreCase(e.getValue(false))) {
    -  127  0
                     final Evidence newEvidence = new Evidence(e.getSource() + " (hint)", e.getName(), "sun", e.getConfidence());
    -  128  0
                     newEntries.add(newEvidence);
    -  129   -
                 }
    -  130  26
             }
    -  131  2
             for (Evidence e : newEntries) {
    -  132  0
                 dependency.getVendorEvidence().addEvidence(e);
    -  133  0
             }
    -  134  
     
    -  135  2
         }
    -  136   +  119  16
             if (vendor.contains(springTest4)) {
    +  120  8
                 dependency.getProductEvidence().addEvidence("hint analyzer", "product", "springsource_spring_framework", Confidence.HIGH);
    +  121  8
                 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "vmware", Confidence.HIGH);
    +  122  8
                 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "pivotal", Confidence.HIGH);
    +  123   +
             }
    +  124   +
     
    +  125  16
             if (product.contains(springSecurityTest1) || product.contains(springSecurityTest2)) {
    +  126  0
                 dependency.getProductEvidence().addEvidence("hint analyzer", "product", "springsource_spring_security", Confidence.HIGH);
    +  127  0
                 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "SpringSource", Confidence.HIGH);
    +  128  0
                 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "vmware", Confidence.HIGH);
    +  129   +
             }
    +  130   +
     
    +  131   +
             //sun/oracle problem
    +  132  16
             final Iterator<Evidence> itr = dependency.getVendorEvidence().iterator();
    +  133  16
             final List<Evidence> newEntries = new ArrayList<Evidence>();
    +  134  216
             while (itr.hasNext()) {
    +  135  200
                 final Evidence e = itr.next();
    +  136  200
                 if ("sun".equalsIgnoreCase(e.getValue(false))) {
    +  137  0
                     final Evidence newEvidence = new Evidence(e.getSource() + " (hint)", e.getName(), "oracle", e.getConfidence());
    +  138  0
                     newEntries.add(newEvidence);
    +  139  0
                 } else if ("oracle".equalsIgnoreCase(e.getValue(false))) {
    +  140  0
                     final Evidence newEvidence = new Evidence(e.getSource() + " (hint)", e.getName(), "sun", e.getConfidence());
    +  141  0
                     newEntries.add(newEvidence);
    +  142   +
                 }
    +  143  200
             }
    +  144  16
             for (Evidence e : newEntries) {
    +  145  0
                 dependency.getVendorEvidence().addEvidence(e);
    +  146  0
             }
    +  147   +
     
    +  148  16
         }
    +  149  
     }
    - + 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 f34d35160..d90657d5c 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
    62%
    299/481
    50%
    163/326
    7.032
    JarAnalyzer$ClassNameInformation
    80%
    17/21
    80%
    8/10
    7.032
    JarAnalyzer
    62%
    301/481
    49%
    164/332
    7.129
    JarAnalyzer$ClassNameInformation
    80%
    17/21
    80%
    8/10
    7.129
     
    @@ -61,65 +61,65 @@  21  
     import java.io.File;
     22   -
     import java.io.FileOutputStream;
    +
     import java.io.FileFilter;
     23   -
     import java.io.IOException;
    +
     import java.io.FileOutputStream;
     24   -
     import java.io.InputStream;
    +
     import java.io.IOException;
     25   -
     import java.io.InputStreamReader;
    +
     import java.io.InputStream;
     26   -
     import java.io.OutputStream;
    +
     import java.io.InputStreamReader;
     27   -
     import java.io.Reader;
    +
     import java.io.OutputStream;
     28   -
     import java.util.ArrayList;
    +
     import java.io.Reader;
     29   -
     import java.util.Collections;
    +
     import java.util.ArrayList;
     30   -
     import java.util.Enumeration;
    +
     import java.util.Collections;
     31   -
     import java.util.HashMap;
    +
     import java.util.Enumeration;
     32   -
     import java.util.List;
    +
     import java.util.HashMap;
     33   -
     import java.util.Map;
    +
     import java.util.List;
     34   -
     import java.util.Map.Entry;
    +
     import java.util.Map;
     35   -
     import java.util.Properties;
    +
     import java.util.Map.Entry;
     36   -
     import java.util.Set;
    +
     import java.util.Properties;
     37   -
     import java.util.StringTokenizer;
    +
     import java.util.Set;
     38   -
     import java.util.jar.Attributes;
    +
     import java.util.StringTokenizer;
     39   -
     import java.util.jar.JarEntry;
    +
     import java.util.jar.Attributes;
     40   -
     import java.util.jar.JarFile;
    +
     import java.util.jar.JarEntry;
     41   -
     import java.util.jar.Manifest;
    +
     import java.util.jar.JarFile;
     42   -
     import java.util.logging.Level;
    +
     import java.util.jar.Manifest;
     43   -
     import java.util.logging.Logger;
    -  44  
     import java.util.regex.Pattern;
    -  45   +  44  
     import java.util.zip.ZipEntry;
    -  46   +  45  
     import org.jsoup.Jsoup;
    -  47   +  46  
     import org.owasp.dependencycheck.Engine;
    -  48   +  47  
     import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
    -  49   +  48  
     import org.owasp.dependencycheck.dependency.Confidence;
    -  50   +  49  
     import org.owasp.dependencycheck.dependency.Dependency;
    -  51   +  50  
     import org.owasp.dependencycheck.dependency.EvidenceCollection;
    +  51   +
     import org.owasp.dependencycheck.utils.FileFilterBuilder;
     52  
     import org.owasp.dependencycheck.xml.pom.License;
     53   @@ -131,247 +131,246 @@  56  
     import org.owasp.dependencycheck.utils.Settings;
     57   -
     
    +
     import org.slf4j.Logger;
     58   -
     /**
    +
     import org.slf4j.LoggerFactory;
     59   -
      * Used to load a JAR file and collect information that can be used to determine the associated CPE.
    +
     
     60   -
      *
    +
     /**
     61   -
      * @author Jeremy Long
    +
      * Used to load a JAR file and collect information that can be used to determine the associated CPE.
     62   -
      */
    +
      *
     63   -
     public class JarAnalyzer extends AbstractFileTypeAnalyzer {
    +
      * @author Jeremy Long
     64   -
     
    +
      */
     65   -
         //<editor-fold defaultstate="collapsed" desc="Constants and Member Variables">
    +
     public class JarAnalyzer extends AbstractFileTypeAnalyzer {
     66   -
         /**
    +
     
     67   -
          * The logger.
    +
         //<editor-fold defaultstate="collapsed" desc="Constants and Member Variables">
     68   -
          */
    -  69  1
         private static final Logger LOGGER = Logger.getLogger(JarAnalyzer.class.getName());
    +
         /**
    +  69   +
          * The logger.
     70   -
         /**
    -  71   -
          * The buffer size to use when extracting files from the archive.
    +
          */
    +  71  8
         private static final Logger LOGGER = LoggerFactory.getLogger(JarAnalyzer.class);
     72   -
          */
    +
         /**
     73   -
         private static final int BUFFER_SIZE = 4096;
    +
          * The buffer size to use when extracting files from the archive.
     74   -
         /**
    +
          */
     75   -
          * The count of directories created during analysis. This is used for creating temporary directories.
    +
         private static final int BUFFER_SIZE = 4096;
     76   -
          */
    -  77  1
         private static int dirCount = 0;
    +
         /**
    +  77   +
          * The count of directories created during analysis. This is used for creating temporary directories.
     78   -
         /**
    -  79   -
          * The system independent newline character.
    +
          */
    +  79  8
         private static int dirCount = 0;
     80   -
          */
    -  81  1
         private static final String NEWLINE = System.getProperty("line.separator");
    +
         /**
    +  81   +
          * The system independent newline character.
     82   -
         /**
    -  83   -
          * A list of values in the manifest to ignore as they only result in false positives.
    +
          */
    +  83  8
         private static final String NEWLINE = System.getProperty("line.separator");
     84   -
          */
    -  85  1
         private static final Set<String> IGNORE_VALUES = newHashSet(
    +
         /**
    +  85   +
          * A list of values in the manifest to ignore as they only result in false positives.
     86   -
                 "Sun Java System Application Server");
    -  87   -
         /**
    +
          */
    +  87  8
         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  8
         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   -
                 "include-resource",
    +
                 "bundle-manifestversion",
     120   -
                 "embed-dependency",
    +
                 "bundlemanifestversion",
     121   -
                 "ipojo-components",
    +
                 "bundle-vendor",
     122   -
                 "ipojo-extension",
    +
                 "include-resource",
     123   -
                 "eclipse-sourcereferences");
    +
                 "embed-dependency",
     124   -
         /**
    +
                 "ipojo-components",
     125   -
          * item in some manifest, should be considered medium confidence.
    +
                 "ipojo-extension",
     126   -
          */
    +
                 "eclipse-sourcereferences");
     127   -
         private static final String BUNDLE_VERSION = "Bundle-Version"; //: 2.1.2
    +
         /**
     128   -
         /**
    +
          * Deprecated Jar manifest attribute, that is, nonetheless, useful for analysis.
     129   -
          * item in some manifest, should be considered medium confidence.
    +
          */
     130   -
          */
    -  131   -
         private static final String BUNDLE_DESCRIPTION = "Bundle-Description"; //: Apache Struts 2
    +
         @SuppressWarnings("deprecation")
    +  131  8
         private static final String IMPLEMENTATION_VENDOR_ID = Attributes.Name.IMPLEMENTATION_VENDOR_ID
     132   -
         /**
    +
                 .toString();
     133   -
          * item in some manifest, should be considered medium confidence.
    +
         /**
     134   -
          */
    -  135   -
         private static final String BUNDLE_NAME = "Bundle-Name"; //: Struts 2 Core
    -  136   -
         /**
    -  137  
          * item in some manifest, should be considered medium confidence.
    +  135   +
          */
    +  136   +
         private static final String BUNDLE_VERSION = "Bundle-Version"; //: 2.1.2
    +  137   +
         /**
     138   -
          */
    +
          * item in some manifest, should be considered medium confidence.
     139   -
         private static final String BUNDLE_VENDOR = "Bundle-Vendor"; //: Apache Software Foundation
    +
          */
     140   -
         /**
    +
         private static final String BUNDLE_DESCRIPTION = "Bundle-Description"; //: Apache Struts 2
     141   -
          * A pattern to detect HTML within text.
    +
         /**
     142   +
          * item in some manifest, should be considered medium confidence.
    +  143  
          */
    -  143  1
         private static final Pattern HTML_DETECTION_PATTERN = Pattern.compile("\\<[a-z]+.*/?\\>", Pattern.CASE_INSENSITIVE);
     144   -
     
    +
         private static final String BUNDLE_NAME = "Bundle-Name"; //: Struts 2 Core
     145   -
         //</editor-fold>
    +
         /**
     146   -
         /**
    +
          * A pattern to detect HTML within text.
     147   -
          * Constructs a new JarAnalyzer.
    -  148  
          */
    -  149  6
         public JarAnalyzer() {
    -  150  6
         }
    +  148  8
         private static final Pattern HTML_DETECTION_PATTERN = Pattern.compile("\\<[a-z]+.*/?\\>", Pattern.CASE_INSENSITIVE);
    +  149   +
     
    +  150   +
         //</editor-fold>
     151   -
     
    +
         /**
     152   -
         //<editor-fold defaultstate="collapsed" desc="All standard implmentation details of Analyzer">
    +
          * Constructs a new JarAnalyzer.
     153   -
         /**
    -  154   -
          * The name of the analyzer.
    -  155  
          */
    +  154  48
         public JarAnalyzer() {
    +  155  48
         }
     156   -
         private static final String ANALYZER_NAME = "Jar Analyzer";
    -  157   -
         /**
    -  158   -
          * The phase that this analyzer is intended to run in.
    -  159   -
          */
    -  160  1
         private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
    -  161   -
         /**
    -  162   -
          * The set of file extensions supported by this analyzer.
    -  163   -
          */
    -  164  1
         private static final Set<String> EXTENSIONS = newHashSet("jar", "war");
    -  165  
     
    +  157   +
         //<editor-fold defaultstate="collapsed" desc="All standard implmentation details of Analyzer">
    +  158   +
         /**
    +  159   +
          * The name of the analyzer.
    +  160   +
          */
    +  161   +
         private static final String ANALYZER_NAME = "Jar Analyzer";
    +  162   +
         /**
    +  163   +
          * The phase that this analyzer is intended to run in.
    +  164   +
          */
    +  165  8
         private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
     166  
         /**
     167   -
          * Returns a list of file EXTENSIONS supported by this analyzer.
    +
          * The set of file extensions supported by this analyzer.
     168   -
          *
    -  169   -
          * @return a list of file EXTENSIONS supported by this analyzer.
    -  170  
          */
    +  169  8
         private static final String[] EXTENSIONS = {"jar", "war"};
    +  170   +
     
     171   -
         @Override
    +
         /**
     172   -
         public Set<String> getSupportedExtensions() {
    -  173  852
             return EXTENSIONS;
    -  174   -
         }
    +
          * The file filter used to determine which files this analyzer supports.
    +  173   +
          */
    +  174  8
         private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(EXTENSIONS).build();
     175  
     
     176  
         /**
     177   -
          * Returns the name of the analyzer.
    +
          * Returns the FileFilter.
     178  
          *
     179   -
          * @return the name of the analyzer.
    +
          * @return the FileFilter
     180  
          */
     181  
         @Override
     182   -
         public String getName() {
    -  183  5
             return ANALYZER_NAME;
    +
         protected FileFilter getFileFilter() {
    +  183  6840
             return FILTER;
     184  
         }
     185   @@ -379,1503 +378,1528 @@  186  
         /**
     187   -
          * Returns the phase that the analyzer is intended to run in.
    +
          * Returns the name of the analyzer.
     188  
          *
     189   -
          * @return the phase that the analyzer is intended to run in.
    +
          * @return the name of the analyzer.
     190  
          */
     191   -
         public AnalysisPhase getAnalysisPhase() {
    -  192  1
             return ANALYSIS_PHASE;
    -  193   -
         }
    +
         @Override
    +  192   +
         public String getName() {
    +  193  40
             return ANALYZER_NAME;
     194   -
         //</editor-fold>
    +
         }
     195  
     
     196  
         /**
     197   -
          * Returns the key used in the properties file to reference the analyzer's enabled property.
    +
          * Returns the phase that the analyzer is intended to run in.
     198  
          *
     199   -
          * @return the analyzer's enabled property setting key
    +
          * @return the phase that the analyzer is intended to run in.
     200  
          */
     201   -
         @Override
    -  202   -
         protected String getAnalyzerEnabledSettingKey() {
    -  203  6
             return Settings.KEYS.ANALYZER_JAR_ENABLED;
    -  204   +
         public AnalysisPhase getAnalysisPhase() {
    +  202  16
             return ANALYSIS_PHASE;
    +  203  
         }
    +  204   +
         //</editor-fold>
     205  
     
     206  
         /**
     207   -
          * Loads a specified JAR file and collects information from the manifest and checksums to identify the correct CPE
    +
          * Returns the key used in the properties file to reference the analyzer's enabled property.
     208   -
          * information.
    +
          *
     209   -
          *
    +
          * @return the analyzer's enabled property setting key
     210   -
          * @param dependency the dependency to analyze.
    +
          */
     211   -
          * @param engine the engine that is scanning the dependencies
    -  212   -
          * @throws AnalysisException is thrown if there is an error reading the JAR file.
    -  213   -
          */
    -  214  
         @Override
    +  212   +
         protected String getAnalyzerEnabledSettingKey() {
    +  213  48
             return Settings.KEYS.ANALYZER_JAR_ENABLED;
    +  214   +
         }
     215   -
         public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException {
    -  216   -
             try {
    -  217  5
                 final List<ClassNameInformation> classNames = collectClassNames(dependency);
    -  218  5
                 final String fileName = dependency.getFileName().toLowerCase();
    -  219  5
                 if (classNames.isEmpty()
    -  220   -
                         && (fileName.endsWith("-sources.jar")
    -  221   -
                         || fileName.endsWith("-javadoc.jar")
    -  222   -
                         || fileName.endsWith("-src.jar")
    -  223   -
                         || fileName.endsWith("-doc.jar"))) {
    -  224  0
                     engine.getDependencies().remove(dependency);
    -  225   -
                 }
    -  226  5
                 final boolean hasManifest = parseManifest(dependency, classNames);
    -  227  5
                 final boolean hasPOM = analyzePOM(dependency, classNames, engine);
    -  228  5
                 final boolean addPackagesAsEvidence = !(hasManifest && hasPOM);
    -  229  5
                 analyzePackageNames(classNames, dependency, addPackagesAsEvidence);
    -  230  0
             } catch (IOException ex) {
    -  231  0
                 throw new AnalysisException("Exception occurred reading the JAR file.", ex);
    -  232  5
             }
    -  233  5
         }
    -  234  
     
    -  235   +  216  
         /**
    -  236   -
          * Attempts to find a pom.xml within the JAR file. If found it extracts information and adds it to the evidence. This will
    -  237   -
          * attempt to interpolate the strings contained within the pom.properties if one exists.
    -  238   +  217   +
          * Loads a specified JAR file and collects information from the manifest and checksums to identify the correct CPE
    +  218   +
          * information.
    +  219  
          *
    -  239   -
          * @param dependency the dependency being analyzed
    -  240   -
          * @param classes a collection of class name information
    -  241   -
          * @param engine the analysis engine, used to add additional dependencies
    -  242   -
          * @throws AnalysisException is thrown if there is an exception parsing the pom
    -  243   -
          * @return whether or not evidence was added to the dependency
    -  244   +  220   +
          * @param dependency the dependency to analyze.
    +  221   +
          * @param engine the engine that is scanning the dependencies
    +  222   +
          * @throws AnalysisException is thrown if there is an error reading the JAR file.
    +  223  
          */
    -  245   -
         protected boolean analyzePOM(Dependency dependency, List<ClassNameInformation> classes, Engine engine) throws AnalysisException {
    -  246  5
             boolean foundSomething = false;
    -  247   -
             final JarFile jar;
    -  248   +  224   +
         @Override
    +  225   +
         public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException {
    +  226  
             try {
    -  249  5
                 jar = new JarFile(dependency.getActualFilePath());
    -  250  0
             } catch (IOException ex) {
    -  251  0
                 final String msg = String.format("Unable to read JarFile '%s'.", dependency.getActualFilePath());
    +  227  40
                 final List<ClassNameInformation> classNames = collectClassNames(dependency);
    +  228  40
                 final String fileName = dependency.getFileName().toLowerCase();
    +  229  40
                 if (classNames.isEmpty()
    +  230   +
                         && (fileName.endsWith("-sources.jar")
    +  231   +
                         || fileName.endsWith("-javadoc.jar")
    +  232   +
                         || fileName.endsWith("-src.jar")
    +  233   +
                         || fileName.endsWith("-doc.jar"))) {
    +  234  0
                     engine.getDependencies().remove(dependency);
    +  235   +
                 }
    +  236  40
                 final boolean hasManifest = parseManifest(dependency, classNames);
    +  237  40
                 final boolean hasPOM = analyzePOM(dependency, classNames, engine);
    +  238  40
                 final boolean addPackagesAsEvidence = !(hasManifest && hasPOM);
    +  239  40
                 analyzePackageNames(classNames, dependency, addPackagesAsEvidence);
    +  240  0
             } catch (IOException ex) {
    +  241  0
                 throw new AnalysisException("Exception occurred reading the JAR file.", ex);
    +  242  40
             }
    +  243  40
         }
    +  244   +
     
    +  245   +
         /**
    +  246   +
          * Attempts to find a pom.xml within the JAR file. If found it extracts information and adds it to the evidence. This will
    +  247   +
          * attempt to interpolate the strings contained within the pom.properties if one exists.
    +  248   +
          *
    +  249   +
          * @param dependency the dependency being analyzed
    +  250   +
          * @param classes a collection of class name information
    +  251   +
          * @param engine the analysis engine, used to add additional dependencies
     252   -
                 //final AnalysisException ax = new AnalysisException(msg, ex);
    -  253  0
                 LOGGER.log(Level.WARNING, msg);
    -  254  0
                 LOGGER.log(Level.FINE, "", ex);
    -  255  0
                 return false;
    -  256  5
             }
    +
          * @throws AnalysisException is thrown if there is an exception parsing the pom
    +  253   +
          * @return whether or not evidence was added to the dependency
    +  254   +
          */
    +  255   +
         protected boolean analyzePOM(Dependency dependency, List<ClassNameInformation> classes, Engine engine) throws AnalysisException {
    +  256  40
             boolean foundSomething = false;
     257   -
             List<String> pomEntries;
    +
             final JarFile jar;
     258  
             try {
    -  259  5
                 pomEntries = retrievePomListing(jar);
    +  259  40
                 jar = new JarFile(dependency.getActualFilePath());
     260  0
             } catch (IOException ex) {
    -  261  0
                 final String msg = String.format("Unable to read Jar file entries in '%s'.", dependency.getActualFilePath());
    -  262   -
                 //final AnalysisException ax = new AnalysisException(msg, ex);
    -  263  0
                 LOGGER.log(Level.WARNING, msg);
    -  264  0
                 LOGGER.log(Level.FINE, msg, ex);
    -  265  0
                 return false;
    -  266  5
             }
    -  267  5
             File externalPom = null;
    -  268  5
             if (pomEntries.isEmpty()) {
    -  269  4
                 String pomPath = dependency.getActualFilePath();
    -  270  4
                 pomPath = pomPath.substring(0, pomPath.lastIndexOf('.')) + ".pom";
    -  271  4
                 externalPom = new File(pomPath);
    -  272  4
                 if (externalPom.isFile()) {
    -  273  0
                     pomEntries.add(pomPath);
    -  274   -
                 } else {
    -  275  4
                     return false;
    -  276   -
                 }
    -  277   -
             }
    -  278  1
             for (String path : pomEntries) {
    -  279  1
                 LOGGER.fine(String.format("Reading pom entry: %s", path));
    -  280  1
                 Properties pomProperties = null;
    -  281   -
                 try {
    -  282  1
                     if (externalPom == null) {
    -  283  1
                         pomProperties = retrievePomProperties(path, jar);
    -  284   -
                     }
    -  285  0
                 } catch (IOException ex) {
    -  286  0
                     LOGGER.log(Level.FINEST, "ignore this, failed reading a non-existent pom.properties", ex);
    -  287  1
                 }
    -  288  1
                 Model pom = null;
    -  289   -
                 try {
    -  290  1
                     if (pomEntries.size() > 1) {
    -  291   -
                         //extract POM to its own directory and add it as its own dependency
    -  292  0
                         final Dependency newDependency = new Dependency();
    -  293  0
                         pom = extractPom(path, jar, newDependency);
    -  294   -
     
    -  295  0
                         final String displayPath = String.format("%s%s%s",
    -  296   -
                                 dependency.getFilePath(),
    -  297   -
                                 File.separator,
    -  298   -
                                 path);
    -  299  0
                         final String displayName = String.format("%s%s%s",
    -  300   -
                                 dependency.getFileName(),
    -  301   -
                                 File.separator,
    -  302   -
                                 path);
    -  303   -
     
    -  304  0
                         newDependency.setFileName(displayName);
    -  305  0
                         newDependency.setFilePath(displayPath);
    -  306  0
                         pom.processProperties(pomProperties);
    -  307  0
                         setPomEvidence(newDependency, pom, null);
    -  308  0
                         engine.getDependencies().add(newDependency);
    -  309  0
                         Collections.sort(engine.getDependencies());
    -  310  0
                     } else {
    -  311  1
                         if (externalPom == null) {
    -  312  1
                             pom = PomUtils.readPom(path, jar);
    -  313   -
                         } else {
    -  314  0
                             pom = PomUtils.readPom(externalPom);
    -  315   -
                         }
    -  316  1
                         pom.processProperties(pomProperties);
    -  317  1
                         foundSomething |= setPomEvidence(dependency, pom, classes);
    -  318   -
                     }
    -  319  0
                 } catch (AnalysisException ex) {
    -  320  0
                     final String msg = String.format("An error occured while analyzing '%s'.", dependency.getActualFilePath());
    -  321  0
                     LOGGER.log(Level.WARNING, msg);
    -  322  0
                     LOGGER.log(Level.FINE, "", ex);
    -  323  1
                 }
    -  324  1
             }
    -  325  1
             return foundSomething;
    -  326   -
         }
    -  327   -
     
    -  328   -
         /**
    -  329   -
          * Given a path to a pom.xml within a JarFile, this method attempts to load a sibling pom.properties if one exists.
    -  330   -
          *
    -  331   -
          * @param path the path to the pom.xml within the JarFile
    -  332   -
          * @param jar the JarFile to load the pom.properties from
    -  333   -
          * @return a Properties object or null if no pom.properties was found
    -  334   -
          * @throws IOException thrown if there is an exception reading the pom.properties
    -  335   -
          */
    -  336   -
         private Properties retrievePomProperties(String path, final JarFile jar) throws IOException {
    -  337  1
             Properties pomProperties = null;
    -  338  1
             final String propPath = path.substring(0, path.length() - 7) + "pom.properies";
    -  339  1
             final ZipEntry propEntry = jar.getEntry(propPath);
    -  340  1
             if (propEntry != null) {
    -  341  0
                 Reader reader = null;
    -  342   -
                 try {
    -  343  0
                     reader = new InputStreamReader(jar.getInputStream(propEntry), "UTF-8");
    -  344  0
                     pomProperties = new Properties();
    -  345  0
                     pomProperties.load(reader);
    -  346  0
                     LOGGER.fine(String.format("Read pom.properties: %s", propPath));
    -  347   -
                 } finally {
    -  348  0
                     if (reader != null) {
    -  349   -
                         try {
    -  350  0
                             reader.close();
    -  351  0
                         } catch (IOException ex) {
    -  352  0
                             LOGGER.log(Level.FINEST, "close error", ex);
    -  353  0
                         }
    -  354   -
                     }
    -  355   -
                 }
    -  356   -
             }
    -  357  1
             return pomProperties;
    -  358   -
         }
    -  359   -
     
    -  360   -
         /**
    -  361   -
          * Searches a JarFile for pom.xml entries and returns a listing of these entries.
    -  362   -
          *
    -  363   -
          * @param jar the JarFile to search
    -  364   -
          * @return a list of pom.xml entries
    -  365   -
          * @throws IOException thrown if there is an exception reading a JarEntry
    -  366   -
          */
    -  367   -
         private List<String> retrievePomListing(final JarFile jar) throws IOException {
    -  368  5
             final List<String> pomEntries = new ArrayList<String>();
    -  369  5
             final Enumeration<JarEntry> entries = jar.entries();
    -  370  1848
             while (entries.hasMoreElements()) {
    -  371  1843
                 final JarEntry entry = entries.nextElement();
    -  372  1843
                 final String entryName = (new File(entry.getName())).getName().toLowerCase();
    -  373  1843
                 if (!entry.isDirectory() && "pom.xml".equals(entryName)) {
    -  374  1
                     LOGGER.fine(String.format("POM Entry found: %s", entry.getName()));
    -  375  1
                     pomEntries.add(entry.getName());
    -  376   -
                 }
    -  377  1843
             }
    -  378  5
             return pomEntries;
    -  379   -
         }
    -  380   -
     
    -  381   -
         /**
    -  382   -
          * Retrieves the specified POM from a jar file and converts it to a Model.
    -  383   -
          *
    -  384   -
          * @param path the path to the pom.xml file within the jar file
    -  385   -
          * @param jar the jar file to extract the pom from
    -  386   -
          * @param dependency the dependency being analyzed
    -  387   -
          * @return returns the POM object
    -  388   -
          * @throws AnalysisException is thrown if there is an exception extracting or parsing the POM
    -  389   -
          * {@link org.owasp.dependencycheck.jaxb.pom.generated.Model} object
    -  390   -
          */
    -  391   -
         private Model extractPom(String path, JarFile jar, Dependency dependency) throws AnalysisException {
    -  392  0
             InputStream input = null;
    -  393  0
             FileOutputStream fos = null;
    -  394  0
             BufferedOutputStream bos = null;
    -  395  0
             final File tmpDir = getNextTempDirectory();
    -  396  0
             final File file = new File(tmpDir, "pom.xml");
    -  397   +  261  0
                 LOGGER.warn("Unable to read JarFile '{}'.", dependency.getActualFilePath());
    +  262  0
                 LOGGER.trace("", ex);
    +  263  0
                 return false;
    +  264  40
             }
    +  265   +
             List<String> pomEntries;
    +  266  
             try {
    -  398  0
                 final ZipEntry entry = jar.getEntry(path);
    -  399  0
                 input = jar.getInputStream(entry);
    -  400  0
                 fos = new FileOutputStream(file);
    -  401  0
                 bos = new BufferedOutputStream(fos, BUFFER_SIZE);
    -  402   -
                 int count;
    -  403  0
                 final byte[] data = new byte[BUFFER_SIZE];
    -  404  0
                 while ((count = input.read(data, 0, BUFFER_SIZE)) != -1) {
    -  405  0
                     bos.write(data, 0, count);
    -  406   +  267  40
                 pomEntries = retrievePomListing(jar);
    +  268  0
             } catch (IOException ex) {
    +  269  0
                 LOGGER.warn("Unable to read Jar file entries in '{}'.", dependency.getActualFilePath());
    +  270  0
                 LOGGER.trace("", ex);
    +  271  0
                 return false;
    +  272  40
             }
    +  273  40
             File externalPom = null;
    +  274  40
             if (pomEntries.isEmpty()) {
    +  275  32
                 String pomPath = dependency.getActualFilePath();
    +  276  32
                 pomPath = pomPath.substring(0, pomPath.lastIndexOf('.')) + ".pom";
    +  277  32
                 externalPom = new File(pomPath);
    +  278  32
                 if (externalPom.isFile()) {
    +  279  0
                     pomEntries.add(pomPath);
    +  280   +
                 } else {
    +  281  32
                     return false;
    +  282  
                 }
    -  407  0
                 bos.flush();
    -  408  0
                 dependency.setActualFilePath(file.getAbsolutePath());
    -  409  0
             } catch (IOException ex) {
    -  410  0
                 final String msg = String.format("An error occurred reading '%s' from '%s'.", path, dependency.getFilePath());
    -  411  0
                 LOGGER.warning(msg);
    -  412  0
                 LOGGER.log(Level.SEVERE, "", ex);
    -  413   -
             } finally {
    -  414  0
                 closeStream(bos);
    -  415  0
                 closeStream(fos);
    -  416  0
                 closeStream(input);
    -  417  0
             }
    -  418  0
             return PomUtils.readPom(file);
    -  419   +  283   +
             }
    +  284  8
             for (String path : pomEntries) {
    +  285  8
                 LOGGER.debug("Reading pom entry: {}", path);
    +  286  8
                 Properties pomProperties = null;
    +  287   +
                 try {
    +  288  8
                     if (externalPom == null) {
    +  289  8
                         pomProperties = retrievePomProperties(path, jar);
    +  290   +
                     }
    +  291  0
                 } catch (IOException ex) {
    +  292  0
                     LOGGER.trace("ignore this, failed reading a non-existent pom.properties", ex);
    +  293  8
                 }
    +  294  8
                 Model pom = null;
    +  295   +
                 try {
    +  296  8
                     if (pomEntries.size() > 1) {
    +  297   +
                         //extract POM to its own directory and add it as its own dependency
    +  298  0
                         final Dependency newDependency = new Dependency();
    +  299  0
                         pom = extractPom(path, jar, newDependency);
    +  300   +
     
    +  301  0
                         final String displayPath = String.format("%s%s%s",
    +  302   +
                                 dependency.getFilePath(),
    +  303   +
                                 File.separator,
    +  304   +
                                 path);
    +  305  0
                         final String displayName = String.format("%s%s%s",
    +  306   +
                                 dependency.getFileName(),
    +  307   +
                                 File.separator,
    +  308   +
                                 path);
    +  309   +
     
    +  310  0
                         newDependency.setFileName(displayName);
    +  311  0
                         newDependency.setFilePath(displayPath);
    +  312  0
                         pom.processProperties(pomProperties);
    +  313  0
                         setPomEvidence(newDependency, pom, null);
    +  314  0
                         engine.getDependencies().add(newDependency);
    +  315  0
                         Collections.sort(engine.getDependencies());
    +  316  0
                     } else {
    +  317  8
                         if (externalPom == null) {
    +  318  8
                             pom = PomUtils.readPom(path, jar);
    +  319   +
                         } else {
    +  320  0
                             pom = PomUtils.readPom(externalPom);
    +  321   +
                         }
    +  322  8
                         pom.processProperties(pomProperties);
    +  323  8
                         foundSomething |= setPomEvidence(dependency, pom, classes);
    +  324   +
                     }
    +  325  0
                 } catch (AnalysisException ex) {
    +  326  0
                     LOGGER.warn("An error occured while analyzing '{}'.", dependency.getActualFilePath());
    +  327  0
                     LOGGER.trace("", ex);
    +  328  8
                 }
    +  329  8
             }
    +  330  8
             return foundSomething;
    +  331  
         }
    -  420   +  332  
     
    -  421   +  333  
         /**
    -  422   -
          * Silently closes an input stream ignoring errors.
    +  334   +
          * Given a path to a pom.xml within a JarFile, this method attempts to load a sibling pom.properties if one exists.
    +  335   +
          *
    +  336   +
          * @param path the path to the pom.xml within the JarFile
    +  337   +
          * @param jar the JarFile to load the pom.properties from
    +  338   +
          * @return a Properties object or null if no pom.properties was found
    +  339   +
          * @throws IOException thrown if there is an exception reading the pom.properties
    +  340   +
          */
    +  341   +
         private Properties retrievePomProperties(String path, final JarFile jar) throws IOException {
    +  342  8
             Properties pomProperties = null;
    +  343  8
             final String propPath = path.substring(0, path.length() - 7) + "pom.properies";
    +  344  8
             final ZipEntry propEntry = jar.getEntry(propPath);
    +  345  8
             if (propEntry != null) {
    +  346  0
                 Reader reader = null;
    +  347   +
                 try {
    +  348  0
                     reader = new InputStreamReader(jar.getInputStream(propEntry), "UTF-8");
    +  349  0
                     pomProperties = new Properties();
    +  350  0
                     pomProperties.load(reader);
    +  351  0
                     LOGGER.debug("Read pom.properties: {}", propPath);
    +  352   +
                 } finally {
    +  353  0
                     if (reader != null) {
    +  354   +
                         try {
    +  355  0
                             reader.close();
    +  356  0
                         } catch (IOException ex) {
    +  357  0
                             LOGGER.trace("close error", ex);
    +  358  0
                         }
    +  359   +
                     }
    +  360   +
                 }
    +  361   +
             }
    +  362  8
             return pomProperties;
    +  363   +
         }
    +  364   +
     
    +  365   +
         /**
    +  366   +
          * Searches a JarFile for pom.xml entries and returns a listing of these entries.
    +  367   +
          *
    +  368   +
          * @param jar the JarFile to search
    +  369   +
          * @return a list of pom.xml entries
    +  370   +
          * @throws IOException thrown if there is an exception reading a JarEntry
    +  371   +
          */
    +  372   +
         private List<String> retrievePomListing(final JarFile jar) throws IOException {
    +  373  40
             final List<String> pomEntries = new ArrayList<String>();
    +  374  40
             final Enumeration<JarEntry> entries = jar.entries();
    +  375  14784
             while (entries.hasMoreElements()) {
    +  376  14744
                 final JarEntry entry = entries.nextElement();
    +  377  14744
                 final String entryName = (new File(entry.getName())).getName().toLowerCase();
    +  378  14744
                 if (!entry.isDirectory() && "pom.xml".equals(entryName)) {
    +  379  8
                     LOGGER.trace("POM Entry found: {}", entry.getName());
    +  380  8
                     pomEntries.add(entry.getName());
    +  381   +
                 }
    +  382  14744
             }
    +  383  40
             return pomEntries;
    +  384   +
         }
    +  385   +
     
    +  386   +
         /**
    +  387   +
          * Retrieves the specified POM from a jar file and converts it to a Model.
    +  388   +
          *
    +  389   +
          * @param path the path to the pom.xml file within the jar file
    +  390   +
          * @param jar the jar file to extract the pom from
    +  391   +
          * @param dependency the dependency being analyzed
    +  392   +
          * @return returns the POM object
    +  393   +
          * @throws AnalysisException is thrown if there is an exception extracting or parsing the POM
    +  394   +
          * {@link org.owasp.dependencycheck.xml.pom.Model} object
    +  395   +
          */
    +  396   +
         private Model extractPom(String path, JarFile jar, Dependency dependency) throws AnalysisException {
    +  397  0
             InputStream input = null;
    +  398  0
             FileOutputStream fos = null;
    +  399  0
             BufferedOutputStream bos = null;
    +  400  0
             final File tmpDir = getNextTempDirectory();
    +  401  0
             final File file = new File(tmpDir, "pom.xml");
    +  402   +
             try {
    +  403  0
                 final ZipEntry entry = jar.getEntry(path);
    +  404  0
                 input = jar.getInputStream(entry);
    +  405  0
                 fos = new FileOutputStream(file);
    +  406  0
                 bos = new BufferedOutputStream(fos, BUFFER_SIZE);
    +  407   +
                 int count;
    +  408  0
                 final byte[] data = new byte[BUFFER_SIZE];
    +  409  0
                 while ((count = input.read(data, 0, BUFFER_SIZE)) != -1) {
    +  410  0
                     bos.write(data, 0, count);
    +  411   +
                 }
    +  412  0
                 bos.flush();
    +  413  0
                 dependency.setActualFilePath(file.getAbsolutePath());
    +  414  0
             } catch (IOException ex) {
    +  415  0
                 LOGGER.warn("An error occurred reading '{}' from '{}'.", path, dependency.getFilePath());
    +  416  0
                 LOGGER.error("", ex);
    +  417   +
             } finally {
    +  418  0
                 closeStream(bos);
    +  419  0
                 closeStream(fos);
    +  420  0
                 closeStream(input);
    +  421  0
             }
    +  422  0
             return PomUtils.readPom(file);
     423   -
          *
    +
         }
     424   -
          * @param stream an input stream to close
    +
     
     425   -
          */
    +
         /**
     426   -
         private void closeStream(InputStream stream) {
    -  427  0
             if (stream != null) {
    +
          * Silently closes an input stream ignoring errors.
    +  427   +
          *
     428   +
          * @param stream an input stream to close
    +  429   +
          */
    +  430   +
         private void closeStream(InputStream stream) {
    +  431  0
             if (stream != null) {
    +  432  
                 try {
    -  429  0
                     stream.close();
    -  430  0
                 } catch (IOException ex) {
    -  431  0
                     LOGGER.log(Level.FINEST, null, ex);
    -  432  0
                 }
    -  433   -
             }
    -  434  0
         }
    -  435   -
     
    -  436   -
         /**
    +  433  0
                     stream.close();
    +  434  0
                 } catch (IOException ex) {
    +  435  0
                     LOGGER.trace("", ex);
    +  436  0
                 }
     437   -
          * Silently closes an output stream ignoring errors.
    -  438   -
          *
    +
             }
    +  438  0
         }
     439   -
          * @param stream an output stream to close
    +
     
     440   -
          */
    -  441   -
         private void closeStream(OutputStream stream) {
    -  442  0
             if (stream != null) {
    -  443   -
                 try {
    -  444  0
                     stream.close();
    -  445  0
                 } catch (IOException ex) {
    -  446  0
                     LOGGER.log(Level.FINEST, null, ex);
    -  447  0
                 }
    -  448   -
             }
    -  449  0
         }
    -  450   -
     
    -  451  
         /**
    -  452   -
          * Sets evidence from the pom on the supplied dependency.
    -  453   +  441   +
          * Silently closes an output stream ignoring errors.
    +  442  
          *
    -  454   -
          * @param dependency the dependency to set data on
    -  455   -
          * @param pom the information from the pom
    -  456   -
          * @param classes a collection of ClassNameInformation - containing data about the fully qualified class names within the JAR
    -  457   -
          * file being analyzed
    -  458   -
          * @return true if there was evidence within the pom that we could use; otherwise false
    -  459   +  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 about the fully qualified class names within the JAR
    +  461   +
          * file being analyzed
    +  462   +
          * @return true if there was evidence within the pom that we could use; otherwise false
    +  463   +
          */
    +  464  
         public static boolean setPomEvidence(Dependency dependency, Model pom, List<ClassNameInformation> classes) {
    -  461  1
             boolean foundSomething = false;
    -  462  1
             boolean addAsIdentifier = true;
    -  463  1
             if (pom == null) {
    -  464  0
                 return foundSomething;
    -  465   +  465  8
             boolean foundSomething = false;
    +  466  8
             boolean addAsIdentifier = true;
    +  467  8
             if (pom == null) {
    +  468  0
                 return foundSomething;
    +  469  
             }
    -  466  1
             String groupid = pom.getGroupId();
    -  467  1
             String parentGroupId = pom.getParentGroupId();
    -  468  1
             String artifactid = pom.getArtifactId();
    -  469  1
             String parentArtifactId = pom.getParentArtifactId();
    -  470  1
             String version = pom.getVersion();
    -  471  1
             String parentVersion = pom.getParentVersion();
    -  472   +  470  8
             String groupid = pom.getGroupId();
    +  471  8
             String parentGroupId = pom.getParentGroupId();
    +  472  8
             String artifactid = pom.getArtifactId();
    +  473  8
             String parentArtifactId = pom.getParentArtifactId();
    +  474  8
             String version = pom.getVersion();
    +  475  8
             String parentVersion = pom.getParentVersion();
    +  476  
     
    -  473  1
             if ("org.sonatype.oss".equals(parentGroupId) && "oss-parent".equals(parentArtifactId)) {
    -  474  0
                 parentGroupId = null;
    -  475  0
                 parentArtifactId = null;
    -  476  0
                 parentVersion = null;
    -  477   -
             }
    -  478   -
     
    -  479  1
             if ((groupid == null || groupid.isEmpty()) && parentGroupId != null && !parentGroupId.isEmpty()) {
    -  480  0
                 groupid = parentGroupId;
    +  477  8
             if ("org.sonatype.oss".equals(parentGroupId) && "oss-parent".equals(parentArtifactId)) {
    +  478  0
                 parentGroupId = null;
    +  479  0
                 parentArtifactId = null;
    +  480  0
                 parentVersion = null;
     481  
             }
     482  
     
    -  483  1
             final String originalGroupID = groupid;
    -  484  1
             if (groupid.startsWith("org.") || groupid.startsWith("com.")) {
    -  485  1
                 groupid = groupid.substring(4);
    -  486   +  483  8
             if ((groupid == null || groupid.isEmpty()) && parentGroupId != null && !parentGroupId.isEmpty()) {
    +  484  0
                 groupid = parentGroupId;
    +  485  
             }
    -  487   +  486  
     
    -  488  1
             if ((artifactid == null || artifactid.isEmpty()) && parentArtifactId != null && !parentArtifactId.isEmpty()) {
    -  489  0
                 artifactid = parentArtifactId;
    +  487  8
             final String originalGroupID = groupid;
    +  488  8
             if (groupid.startsWith("org.") || groupid.startsWith("com.")) {
    +  489  8
                 groupid = groupid.substring(4);
     490  
             }
     491  
     
    -  492  1
             final String originalArtifactID = artifactid;
    -  493  1
             if (artifactid.startsWith("org.") || artifactid.startsWith("com.")) {
    -  494  0
                 artifactid = artifactid.substring(4);
    -  495   +  492  8
             if ((artifactid == null || artifactid.isEmpty()) && parentArtifactId != null && !parentArtifactId.isEmpty()) {
    +  493  0
                 artifactid = parentArtifactId;
    +  494  
             }
    -  496   +  495  
     
    -  497  1
             if ((version == null || version.isEmpty()) && parentVersion != null && !parentVersion.isEmpty()) {
    -  498  1
                 version = parentVersion;
    +  496  8
             final String originalArtifactID = artifactid;
    +  497  8
             if (artifactid.startsWith("org.") || artifactid.startsWith("com.")) {
    +  498  0
                 artifactid = artifactid.substring(4);
     499  
             }
     500  
     
    -  501  1
             if (groupid != null && !groupid.isEmpty()) {
    -  502  1
                 foundSomething = true;
    -  503  1
                 dependency.getVendorEvidence().addEvidence("pom", "groupid", groupid, Confidence.HIGHEST);
    -  504  1
                 dependency.getProductEvidence().addEvidence("pom", "groupid", groupid, Confidence.LOW);
    -  505  1
                 addMatchingValues(classes, groupid, dependency.getVendorEvidence());
    -  506  1
                 addMatchingValues(classes, groupid, dependency.getProductEvidence());
    -  507  1
                 if (parentGroupId != null && !parentGroupId.isEmpty() && !parentGroupId.equals(groupid)) {
    -  508  1
                     dependency.getVendorEvidence().addEvidence("pom", "parent-groupid", parentGroupId, Confidence.MEDIUM);
    -  509  1
                     dependency.getProductEvidence().addEvidence("pom", "parent-groupid", parentGroupId, Confidence.LOW);
    -  510  1
                     addMatchingValues(classes, parentGroupId, dependency.getVendorEvidence());
    -  511  1
                     addMatchingValues(classes, parentGroupId, dependency.getProductEvidence());
    -  512   -
                 }
    -  513   -
             } else {
    -  514  0
                 addAsIdentifier = false;
    -  515   +  501  8
             if ((version == null || version.isEmpty()) && parentVersion != null && !parentVersion.isEmpty()) {
    +  502  8
                 version = parentVersion;
    +  503  
             }
    +  504   +
     
    +  505  8
             if (groupid != null && !groupid.isEmpty()) {
    +  506  8
                 foundSomething = true;
    +  507  8
                 dependency.getVendorEvidence().addEvidence("pom", "groupid", groupid, Confidence.HIGHEST);
    +  508  8
                 dependency.getProductEvidence().addEvidence("pom", "groupid", groupid, Confidence.LOW);
    +  509  8
                 addMatchingValues(classes, groupid, dependency.getVendorEvidence());
    +  510  8
                 addMatchingValues(classes, groupid, dependency.getProductEvidence());
    +  511  8
                 if (parentGroupId != null && !parentGroupId.isEmpty() && !parentGroupId.equals(groupid)) {
    +  512  8
                     dependency.getVendorEvidence().addEvidence("pom", "parent-groupid", parentGroupId, Confidence.MEDIUM);
    +  513  8
                     dependency.getProductEvidence().addEvidence("pom", "parent-groupid", parentGroupId, Confidence.LOW);
    +  514  8
                     addMatchingValues(classes, parentGroupId, dependency.getVendorEvidence());
    +  515  8
                     addMatchingValues(classes, parentGroupId, dependency.getProductEvidence());
     516   -
     
    -  517  1
             if (artifactid != null && !artifactid.isEmpty()) {
    -  518  1
                 foundSomething = true;
    -  519  1
                 dependency.getProductEvidence().addEvidence("pom", "artifactid", artifactid, Confidence.HIGHEST);
    -  520  1
                 dependency.getVendorEvidence().addEvidence("pom", "artifactid", artifactid, Confidence.LOW);
    -  521  1
                 addMatchingValues(classes, artifactid, dependency.getVendorEvidence());
    -  522  1
                 addMatchingValues(classes, artifactid, dependency.getProductEvidence());
    -  523  1
                 if (parentArtifactId != null && !parentArtifactId.isEmpty() && !parentArtifactId.equals(artifactid)) {
    -  524  1
                     dependency.getProductEvidence().addEvidence("pom", "parent-artifactid", parentArtifactId, Confidence.MEDIUM);
    -  525  1
                     dependency.getVendorEvidence().addEvidence("pom", "parent-artifactid", parentArtifactId, Confidence.LOW);
    -  526  1
                     addMatchingValues(classes, parentArtifactId, dependency.getVendorEvidence());
    -  527  1
                     addMatchingValues(classes, parentArtifactId, dependency.getProductEvidence());
    -  528  
                 }
    -  529   +  517  
             } else {
    -  530  0
                 addAsIdentifier = false;
    -  531   +  518  0
                 addAsIdentifier = false;
    +  519  
             }
    +  520   +
     
    +  521  8
             if (artifactid != null && !artifactid.isEmpty()) {
    +  522  8
                 foundSomething = true;
    +  523  8
                 dependency.getProductEvidence().addEvidence("pom", "artifactid", artifactid, Confidence.HIGHEST);
    +  524  8
                 dependency.getVendorEvidence().addEvidence("pom", "artifactid", artifactid, Confidence.LOW);
    +  525  8
                 addMatchingValues(classes, artifactid, dependency.getVendorEvidence());
    +  526  8
                 addMatchingValues(classes, artifactid, dependency.getProductEvidence());
    +  527  8
                 if (parentArtifactId != null && !parentArtifactId.isEmpty() && !parentArtifactId.equals(artifactid)) {
    +  528  8
                     dependency.getProductEvidence().addEvidence("pom", "parent-artifactid", parentArtifactId, Confidence.MEDIUM);
    +  529  8
                     dependency.getVendorEvidence().addEvidence("pom", "parent-artifactid", parentArtifactId, Confidence.LOW);
    +  530  8
                     addMatchingValues(classes, parentArtifactId, dependency.getVendorEvidence());
    +  531  8
                     addMatchingValues(classes, parentArtifactId, dependency.getProductEvidence());
     532   -
     
    -  533  1
             if (version != null && !version.isEmpty()) {
    -  534  1
                 foundSomething = true;
    -  535  1
                 dependency.getVersionEvidence().addEvidence("pom", "version", version, Confidence.HIGHEST);
    -  536  1
                 if (parentVersion != null && !parentVersion.isEmpty() && !parentVersion.equals(version)) {
    -  537  0
                     dependency.getVersionEvidence().addEvidence("pom", "parent-version", version, Confidence.LOW);
    -  538  
                 }
    -  539   +  533  
             } else {
    -  540  0
                 addAsIdentifier = false;
    -  541   +  534  0
                 addAsIdentifier = false;
    +  535  
             }
    -  542   +  536  
     
    -  543  1
             if (addAsIdentifier) {
    -  544  1
                 dependency.addIdentifier("maven", String.format("%s:%s:%s", originalGroupID, originalArtifactID, version), null, Confidence.HIGH);
    +  537  8
             if (version != null && !version.isEmpty()) {
    +  538  8
                 foundSomething = true;
    +  539  8
                 dependency.getVersionEvidence().addEvidence("pom", "version", version, Confidence.HIGHEST);
    +  540  8
                 if (parentVersion != null && !parentVersion.isEmpty() && !parentVersion.equals(version)) {
    +  541  0
                     dependency.getVersionEvidence().addEvidence("pom", "parent-version", version, Confidence.LOW);
    +  542   +
                 }
    +  543   +
             } else {
    +  544  0
                 addAsIdentifier = false;
     545  
             }
     546  
     
    -  547   +  547  8
             if (addAsIdentifier) {
    +  548  8
                 dependency.addIdentifier("maven", String.format("%s:%s:%s", originalGroupID, originalArtifactID, version), null, Confidence.HIGH);
    +  549   +
             }
    +  550   +
     
    +  551  
             // org name
    -  548  1
             final String org = pom.getOrganization();
    -  549  1
             if (org != null && !org.isEmpty()) {
    -  550  0
                 dependency.getVendorEvidence().addEvidence("pom", "organization name", org, Confidence.HIGH);
    -  551  0
                 dependency.getProductEvidence().addEvidence("pom", "organization name", org, Confidence.LOW);
    -  552  0
                 addMatchingValues(classes, org, dependency.getVendorEvidence());
    -  553  0
                 addMatchingValues(classes, org, dependency.getProductEvidence());
    -  554   -
             }
    -  555   -
             //pom name
    -  556  1
             final String pomName = pom.getName();
    -  557  1
             if (pomName
    +  552  8
             final String org = pom.getOrganization();
    +  553  8
             if (org != null && !org.isEmpty()) {
    +  554  0
                 dependency.getVendorEvidence().addEvidence("pom", "organization name", org, Confidence.HIGH);
    +  555  0
                 dependency.getProductEvidence().addEvidence("pom", "organization name", org, Confidence.LOW);
    +  556  0
                 addMatchingValues(classes, org, dependency.getVendorEvidence());
    +  557  0
                 addMatchingValues(classes, org, dependency.getProductEvidence());
     558   +
             }
    +  559   +
             //pom name
    +  560  8
             final String pomName = pom.getName();
    +  561  8
             if (pomName
    +  562  
                     != null && !pomName.isEmpty()) {
    -  559  1
                 foundSomething = true;
    -  560  1
                 dependency.getProductEvidence().addEvidence("pom", "name", pomName, Confidence.HIGH);
    -  561  1
                 dependency.getVendorEvidence().addEvidence("pom", "name", pomName, Confidence.HIGH);
    -  562  1
                 addMatchingValues(classes, pomName, dependency.getVendorEvidence());
    -  563  1
                 addMatchingValues(classes, pomName, dependency.getProductEvidence());
    -  564   +  563  8
                 foundSomething = true;
    +  564  8
                 dependency.getProductEvidence().addEvidence("pom", "name", pomName, Confidence.HIGH);
    +  565  8
                 dependency.getVendorEvidence().addEvidence("pom", "name", pomName, Confidence.HIGH);
    +  566  8
                 addMatchingValues(classes, pomName, dependency.getVendorEvidence());
    +  567  8
                 addMatchingValues(classes, pomName, dependency.getProductEvidence());
    +  568  
             }
    -  565   +  569  
     
    -  566   +  570  
             //Description
    -  567  1
             final String description = pom.getDescription();
    -  568  1
             if (description != null && !description.isEmpty()) {
    -  569  0
                 foundSomething = true;
    -  570  0
                 final String trimmedDescription = addDescription(dependency, description, "pom", "description");
    -  571  0
                 addMatchingValues(classes, trimmedDescription, dependency.getVendorEvidence());
    -  572  0
                 addMatchingValues(classes, trimmedDescription, dependency.getProductEvidence());
    -  573   -
             }
    -  574   -
     
    -  575  1
             extractLicense(pom, dependency);
    -  576  1
             return foundSomething;
    +  571  8
             final String description = pom.getDescription();
    +  572  8
             if (description != null && !description.isEmpty() && !description.startsWith("POM was created by")) {
    +  573  0
                 foundSomething = true;
    +  574  0
                 final String trimmedDescription = addDescription(dependency, description, "pom", "description");
    +  575  0
                 addMatchingValues(classes, trimmedDescription, dependency.getVendorEvidence());
    +  576  0
                 addMatchingValues(classes, trimmedDescription, dependency.getProductEvidence());
     577   -
         }
    +
             }
     578  
     
    -  579   -
         /**
    -  580   -
          * Analyzes the path information of the classes contained within the JarAnalyzer to try and determine possible vendor or
    +  579  8
             extractLicense(pom, dependency);
    +  580  8
             return foundSomething;
     581   -
          * product names. If any are found they are stored in the packageVendor and packageProduct hashSets.
    +
         }
     582   -
          *
    -  583   -
          * @param classNames a list of class names
    -  584   -
          * @param dependency a dependency to analyze
    -  585   -
          * @param addPackagesAsEvidence a flag indicating whether or not package names should be added as evidence.
    -  586   -
          */
    -  587   -
         protected void analyzePackageNames(List<ClassNameInformation> classNames,
    -  588   -
                 Dependency dependency, boolean addPackagesAsEvidence) {
    -  589  5
             final Map<String, Integer> vendorIdentifiers = new HashMap<String, Integer>();
    -  590  5
             final Map<String, Integer> productIdentifiers = new HashMap<String, Integer>();
    -  591  5
             analyzeFullyQualifiedClassNames(classNames, vendorIdentifiers, productIdentifiers);
    -  592  
     
    -  593  5
             final int classCount = classNames.size();
    -  594  5
             final EvidenceCollection vendor = dependency.getVendorEvidence();
    -  595  5
             final EvidenceCollection product = dependency.getProductEvidence();
    +  583   +
         /**
    +  584   +
          * Analyzes the path information of the classes contained within the JarAnalyzer to try and determine possible vendor or
    +  585   +
          * product names. If any are found they are stored in the packageVendor and packageProduct hashSets.
    +  586   +
          *
    +  587   +
          * @param classNames a list of class names
    +  588   +
          * @param dependency a dependency to analyze
    +  589   +
          * @param addPackagesAsEvidence a flag indicating whether or not package names should be added as evidence.
    +  590   +
          */
    +  591   +
         protected void analyzePackageNames(List<ClassNameInformation> classNames,
    +  592   +
                 Dependency dependency, boolean addPackagesAsEvidence) {
    +  593  40
             final Map<String, Integer> vendorIdentifiers = new HashMap<String, Integer>();
    +  594  40
             final Map<String, Integer> productIdentifiers = new HashMap<String, Integer>();
    +  595  40
             analyzeFullyQualifiedClassNames(classNames, vendorIdentifiers, productIdentifiers);
     596  
     
    -  597  5
             for (Map.Entry<String, Integer> entry : vendorIdentifiers.entrySet()) {
    -  598  48
                 final float ratio = entry.getValue() / (float) classCount;
    -  599  48
                 if (ratio > 0.5) {
    +  597  40
             final int classCount = classNames.size();
    +  598  40
             final EvidenceCollection vendor = dependency.getVendorEvidence();
    +  599  40
             final EvidenceCollection product = dependency.getProductEvidence();
     600   -
                     //TODO remove weighting
    -  601  10
                     vendor.addWeighting(entry.getKey());
    -  602  10
                     if (addPackagesAsEvidence && entry.getKey().length() > 1) {
    -  603  8
                         vendor.addEvidence("jar", "package name", entry.getKey(), Confidence.LOW);
    +
     
    +  601  40
             for (Map.Entry<String, Integer> entry : vendorIdentifiers.entrySet()) {
    +  602  384
                 final float ratio = entry.getValue() / (float) classCount;
    +  603  384
                 if (ratio > 0.5) {
     604   +
                     //TODO remove weighting
    +  605  80
                     vendor.addWeighting(entry.getKey());
    +  606  80
                     if (addPackagesAsEvidence && entry.getKey().length() > 1) {
    +  607  64
                         vendor.addEvidence("jar", "package name", entry.getKey(), Confidence.LOW);
    +  608  
                     }
    -  605   +  609  
                 }
    -  606  48
             }
    -  607  5
             for (Map.Entry<String, Integer> entry : productIdentifiers.entrySet()) {
    -  608  985
                 final float ratio = entry.getValue() / (float) classCount;
    -  609  985
                 if (ratio > 0.5) {
    -  610  5
                     product.addWeighting(entry.getKey());
    -  611  5
                     if (addPackagesAsEvidence && entry.getKey().length() > 1) {
    -  612  4
                         product.addEvidence("jar", "package name", entry.getKey(), Confidence.LOW);
    -  613   -
                     }
    -  614   -
                 }
    -  615  985
             }
    -  616  5
         }
    +  610  384
             }
    +  611  40
             for (Map.Entry<String, Integer> entry : productIdentifiers.entrySet()) {
    +  612  7880
                 final float ratio = entry.getValue() / (float) classCount;
    +  613  7880
                 if (ratio > 0.5) {
    +  614  40
                     product.addWeighting(entry.getKey());
    +  615  40
                     if (addPackagesAsEvidence && entry.getKey().length() > 1) {
    +  616  32
                         product.addEvidence("jar", "package name", entry.getKey(), Confidence.LOW);
     617   -
     
    +
                     }
     618   -
         /**
    -  619   -
          * <p>
    -  620   -
          * Reads the manifest from the JAR file and collects the entries. Some vendorKey entries are:</p>
    +
                 }
    +  619  7880
             }
    +  620  40
         }
     621   -
          * <ul><li>Implementation Title</li>
    +
     
     622   -
          * <li>Implementation Version</li> <li>Implementation Vendor</li>
    +
         /**
     623   -
          * <li>Implementation VendorId</li> <li>Bundle Name</li> <li>Bundle Version</li> <li>Bundle Vendor</li> <li>Bundle
    +
          * <p>
     624   -
          * Description</li> <li>Main Class</li> </ul>
    +
          * Reads the manifest from the JAR file and collects the entries. Some vendorKey entries are:</p>
     625   -
          * However, all but a handful of specific entries are read in.
    +
          * <ul><li>Implementation Title</li>
     626   -
          *
    +
          * <li>Implementation Version</li> <li>Implementation Vendor</li>
     627   -
          * @param dependency A reference to the dependency
    +
          * <li>Implementation VendorId</li> <li>Bundle Name</li> <li>Bundle Version</li> <li>Bundle Vendor</li> <li>Bundle
     628   -
          * @param classInformation a collection of class information
    +
          * Description</li> <li>Main Class</li> </ul>
     629   -
          * @return whether evidence was identified parsing the manifest
    +
          * However, all but a handful of specific entries are read in.
     630   -
          * @throws IOException if there is an issue reading the JAR file
    +
          *
     631   -
          */
    +
          * @param dependency A reference to the dependency
     632   -
         protected boolean parseManifest(Dependency dependency, List<ClassNameInformation> classInformation) throws IOException {
    -  633  5
             boolean foundSomething = false;
    -  634  5
             JarFile jar = null;
    +
          * @param classInformation a collection of class information
    +  633   +
          * @return whether evidence was identified parsing the manifest
    +  634   +
          * @throws IOException if there is an issue reading the JAR file
     635   -
             try {
    -  636  5
                 jar = new JarFile(dependency.getActualFilePath());
    -  637   -
     
    -  638  5
                 final Manifest manifest = jar.getManifest();
    +
          */
    +  636   +
         protected boolean parseManifest(Dependency dependency, List<ClassNameInformation> classInformation) throws IOException {
    +  637  40
             boolean foundSomething = false;
    +  638  40
             JarFile jar = null;
     639   -
     
    -  640  5
                 if (manifest == null) {
    +
             try {
    +  640  40
                 jar = new JarFile(dependency.getActualFilePath());
     641   -
                     //don't log this for javadoc or sources jar files
    -  642  0
                     if (!dependency.getFileName().toLowerCase().endsWith("-sources.jar")
    +
     
    +  642  40
                 final Manifest manifest = jar.getManifest();
     643   -
                             && !dependency.getFileName().toLowerCase().endsWith("-javadoc.jar")
    -  644   -
                             && !dependency.getFileName().toLowerCase().endsWith("-src.jar")
    +
     
    +  644  40
                 if (manifest == null) {
     645   -
                             && !dependency.getFileName().toLowerCase().endsWith("-doc.jar")) {
    -  646  0
                         LOGGER.log(Level.FINE,
    +
                     //don't log this for javadoc or sources jar files
    +  646  0
                     if (!dependency.getFileName().toLowerCase().endsWith("-sources.jar")
     647   -
                                 String.format("Jar file '%s' does not contain a manifest.",
    +
                             && !dependency.getFileName().toLowerCase().endsWith("-javadoc.jar")
     648   -
                                         dependency.getFileName()));
    +
                             && !dependency.getFileName().toLowerCase().endsWith("-src.jar")
     649   -
                     }
    -  650  0
                     return false;
    +
                             && !dependency.getFileName().toLowerCase().endsWith("-doc.jar")) {
    +  650  0
                         LOGGER.debug("Jar file '{}' does not contain a manifest.",
     651   +
                                 dependency.getFileName());
    +  652   +
                     }
    +  653  0
                     return false;
    +  654  
                 }
    -  652  5
                 final Attributes atts = manifest.getMainAttributes();
    -  653   +  655  40
                 final Attributes atts = manifest.getMainAttributes();
    +  656  
     
    -  654  5
                 final EvidenceCollection vendorEvidence = dependency.getVendorEvidence();
    -  655  5
                 final EvidenceCollection productEvidence = dependency.getProductEvidence();
    -  656  5
                 final EvidenceCollection versionEvidence = dependency.getVersionEvidence();
    -  657   +  657  40
                 final EvidenceCollection vendorEvidence = dependency.getVendorEvidence();
    +  658  40
                 final EvidenceCollection productEvidence = dependency.getProductEvidence();
    +  659  40
                 final EvidenceCollection versionEvidence = dependency.getVersionEvidence();
    +  660  
     
    -  658  5
                 final String source = "Manifest";
    -  659   +  661  40
                 final String source = "Manifest";
    +  662  
     
    -  660  5
                 for (Entry<Object, Object> entry : atts.entrySet()) {
    -  661  65
                     String key = entry.getKey().toString();
    -  662  65
                     String value = atts.getValue(key);
    -  663  65
                     if (HTML_DETECTION_PATTERN.matcher(value).find()) {
    -  664  0
                         value = Jsoup.parse(value).text();
    +  663  40
                 String specificationVersion = null;
    +  664  40
                 boolean hasImplementationVersion = false;
     665   +
     
    +  666  40
                 for (Entry<Object, Object> entry : atts.entrySet()) {
    +  667  520
                     String key = entry.getKey().toString();
    +  668  520
                     String value = atts.getValue(key);
    +  669  520
                     if (HTML_DETECTION_PATTERN.matcher(value).find()) {
    +  670  0
                         value = Jsoup.parse(value).text();
    +  671  
                     }
    -  666  65
                     if (IGNORE_VALUES.contains(value)) {
    -  667  0
                         continue;
    -  668  65
                     } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_TITLE.toString())) {
    -  669  1
                         foundSomething = true;
    -  670  1
                         productEvidence.addEvidence(source, key, value, Confidence.HIGH);
    -  671  1
                         addMatchingValues(classInformation, value, productEvidence);
    -  672  64
                     } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VERSION.toString())) {
    -  673  2
                         foundSomething = true;
    -  674  2
                         versionEvidence.addEvidence(source, key, value, Confidence.HIGH);
    -  675  62
                     } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VENDOR.toString())) {
    -  676  1
                         foundSomething = true;
    -  677  1
                         vendorEvidence.addEvidence(source, key, value, Confidence.HIGH);
    -  678  1
                         addMatchingValues(classInformation, value, vendorEvidence);
    -  679  61
                     } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VENDOR_ID.toString())) {
    -  680  0
                         foundSomething = true;
    -  681  0
                         vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
    -  682  0
                         addMatchingValues(classInformation, value, vendorEvidence);
    -  683  61
                     } else if (key.equalsIgnoreCase(BUNDLE_DESCRIPTION)) {
    -  684  2
                         foundSomething = true;
    -  685  2
                         addDescription(dependency, value, "manifest", key);
    -  686   +  672  520
                     if (IGNORE_VALUES.contains(value)) {
    +  673  0
                         continue;
    +  674  520
                     } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_TITLE.toString())) {
    +  675  8
                         foundSomething = true;
    +  676  8
                         productEvidence.addEvidence(source, key, value, Confidence.HIGH);
    +  677  8
                         addMatchingValues(classInformation, value, productEvidence);
    +  678  512
                     } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VERSION.toString())) {
    +  679  16
                         hasImplementationVersion = true;
    +  680  16
                         foundSomething = true;
    +  681  16
                         versionEvidence.addEvidence(source, key, value, Confidence.HIGH);
    +  682  496
                     } else if ("specification-version".equalsIgnoreCase(key)) {
    +  683  8
                         specificationVersion = key;
    +  684  488
                     } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VENDOR.toString())) {
    +  685  8
                         foundSomething = true;
    +  686  8
                         vendorEvidence.addEvidence(source, key, value, Confidence.HIGH);
    +  687  8
                         addMatchingValues(classInformation, value, vendorEvidence);
    +  688  480
                     } else if (key.equalsIgnoreCase(IMPLEMENTATION_VENDOR_ID)) {
    +  689  0
                         foundSomething = true;
    +  690  0
                         vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
    +  691  0
                         addMatchingValues(classInformation, value, vendorEvidence);
    +  692  480
                     } else if (key.equalsIgnoreCase(BUNDLE_DESCRIPTION)) {
    +  693  16
                         foundSomething = true;
    +  694  16
                         addDescription(dependency, value, "manifest", key);
    +  695  
                         //productEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
    -  687  2
                         addMatchingValues(classInformation, value, productEvidence);
    -  688  59
                     } else if (key.equalsIgnoreCase(BUNDLE_NAME)) {
    -  689  3
                         foundSomething = true;
    -  690  3
                         productEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
    -  691  3
                         addMatchingValues(classInformation, value, productEvidence);
    -  692  56
                     } else if (key.equalsIgnoreCase(BUNDLE_VENDOR)) {
    -  693  3
                         foundSomething = true;
    -  694  3
                         vendorEvidence.addEvidence(source, key, value, Confidence.HIGH);
    -  695  3
                         addMatchingValues(classInformation, value, vendorEvidence);
    -  696  53
                     } else if (key.equalsIgnoreCase(BUNDLE_VERSION)) {
    -  697  3
                         foundSomething = true;
    -  698  3
                         versionEvidence.addEvidence(source, key, value, Confidence.HIGH);
    -  699  50
                     } else if (key.equalsIgnoreCase(Attributes.Name.MAIN_CLASS.toString())) {
    -  700  2
                         continue;
    +  696  16
                         addMatchingValues(classInformation, value, productEvidence);
    +  697  464
                     } else if (key.equalsIgnoreCase(BUNDLE_NAME)) {
    +  698  24
                         foundSomething = true;
    +  699  24
                         productEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
    +  700  24
                         addMatchingValues(classInformation, value, productEvidence);
     701   -
                         //skipping main class as if this has important information to add
    +
     //                //the following caused false positives.
     702   -
                         // it will be added during class name analysis...  if other fields
    +
     //                } else if (key.equalsIgnoreCase(BUNDLE_VENDOR)) {
     703   -
                         // have the information from the class name then they will get added...
    -  704  
     //                    foundSomething = true;
    +  704   +
     //                    vendorEvidence.addEvidence(source, key, value, Confidence.HIGH);
     705   -
     //                    productEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
    -  706   -
     //                    vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
    -  707  
     //                    addMatchingValues(classInformation, value, vendorEvidence);
    -  708   -
     //                    addMatchingValues(classInformation, value, productEvidence);
    -  709   -
                     } else {
    -  710  48
                         key = key.toLowerCase();
    +  706  440
                     } else if (key.equalsIgnoreCase(BUNDLE_VERSION)) {
    +  707  24
                         foundSomething = true;
    +  708  24
                         versionEvidence.addEvidence(source, key, value, Confidence.HIGH);
    +  709  416
                     } else if (key.equalsIgnoreCase(Attributes.Name.MAIN_CLASS.toString())) {
    +  710  16
                         continue;
     711   -
     
    -  712  48
                         if (!IGNORE_KEYS.contains(key)
    +
                         //skipping main class as if this has important information to add
    +  712   +
                         // it will be added during class name analysis...  if other fields
     713   -
                                 && !key.endsWith("jdk")
    +
                         // have the information from the class name then they will get added...
     714   -
                                 && !key.contains("lastmodified")
    +
     //                    foundSomething = true;
     715   -
                                 && !key.endsWith("package")
    +
     //                    productEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
     716   -
                                 && !key.endsWith("classpath")
    +
     //                    vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
     717   -
                                 && !key.endsWith("class-path")
    +
     //                    addMatchingValues(classInformation, value, vendorEvidence);
     718   -
                                 && !key.endsWith("-scm") //todo change this to a regex?
    +
     //                    addMatchingValues(classInformation, value, productEvidence);
     719   -
                                 && !key.startsWith("scm-")
    -  720   -
                                 && !value.trim().startsWith("scm:")
    +
                     } else {
    +  720  400
                         key = key.toLowerCase();
     721   -
                                 && !isImportPackage(key, value)
    -  722   -
                                 && !isPackage(key, value)) {
    +
     
    +  722  400
                         if (!IGNORE_KEYS.contains(key)
     723   -
     
    -  724  14
                             foundSomething = true;
    -  725  14
                             if (key.contains("version")) {
    -  726  1
                                 if (key.contains("specification")) {
    -  727  1
                                     versionEvidence.addEvidence(source, key, value, Confidence.LOW);
    +
                                 && !key.endsWith("jdk")
    +  724   +
                                 && !key.contains("lastmodified")
    +  725   +
                                 && !key.endsWith("package")
    +  726   +
                                 && !key.endsWith("classpath")
    +  727   +
                                 && !key.endsWith("class-path")
     728   -
                                 } else {
    -  729  0
                                     versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
    +
                                 && !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   +
     
    +  734  104
                             foundSomething = true;
    +  735  104
                             if (key.contains("version")) {
    +  736  0
                                 if (!key.contains("specification")) {
    +  737   +
                                     //versionEvidence.addEvidence(source, key, value, Confidence.LOW);
    +  738   +
                                     //} else {
    +  739  0
                                     versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
    +  740  
                                 }
    -  731  13
                             } else if ("build-id".equals(key)) {
    -  732  0
                                 int pos = value.indexOf('(');
    -  733  0
                                 if (pos >= 0) {
    -  734  0
                                     value = value.substring(0, pos - 1);
    -  735   +  741  104
                             } else if ("build-id".equals(key)) {
    +  742  0
                                 int pos = value.indexOf('(');
    +  743  0
                                 if (pos >= 0) {
    +  744  0
                                     value = value.substring(0, pos - 1);
    +  745  
                                 }
    -  736  0
                                 pos = value.indexOf('[');
    -  737  0
                                 if (pos >= 0) {
    -  738  0
                                     value = value.substring(0, pos - 1);
    -  739   +  746  0
                                 pos = value.indexOf('[');
    +  747  0
                                 if (pos >= 0) {
    +  748  0
                                     value = value.substring(0, pos - 1);
    +  749  
                                 }
    -  740  0
                                 versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
    -  741  0
                             } else if (key.contains("title")) {
    -  742  1
                                 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
    -  743  1
                                 addMatchingValues(classInformation, value, productEvidence);
    -  744  12
                             } else if (key.contains("vendor")) {
    -  745  0
                                 if (key.contains("specification")) {
    -  746  0
                                     vendorEvidence.addEvidence(source, key, value, Confidence.LOW);
    -  747   +  750  0
                                 versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
    +  751  0
                             } else if (key.contains("title")) {
    +  752  8
                                 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
    +  753  8
                                 addMatchingValues(classInformation, value, productEvidence);
    +  754  96
                             } else if (key.contains("vendor")) {
    +  755  0
                                 if (key.contains("specification")) {
    +  756  0
                                     vendorEvidence.addEvidence(source, key, value, Confidence.LOW);
    +  757  
                                 } else {
    -  748  0
                                     vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
    -  749  0
                                     addMatchingValues(classInformation, value, vendorEvidence);
    -  750   +  758  0
                                     vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
    +  759  0
                                     addMatchingValues(classInformation, value, vendorEvidence);
    +  760  
                                 }
    -  751  12
                             } else if (key.contains("name")) {
    -  752  3
                                 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
    -  753  3
                                 vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
    -  754  3
                                 addMatchingValues(classInformation, value, vendorEvidence);
    -  755  3
                                 addMatchingValues(classInformation, value, productEvidence);
    -  756  9
                             } else if (key.contains("license")) {
    -  757  2
                                 addLicense(dependency, value);
    -  758   +  761  96
                             } else if (key.contains("name")) {
    +  762  24
                                 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
    +  763  24
                                 vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
    +  764  24
                                 addMatchingValues(classInformation, value, vendorEvidence);
    +  765  24
                                 addMatchingValues(classInformation, value, productEvidence);
    +  766  72
                             } else if (key.contains("license")) {
    +  767  16
                                 addLicense(dependency, value);
    +  768  
                             } else {
    -  759  7
                                 if (key.contains("description")) {
    -  760  0
                                     addDescription(dependency, value, "manifest", key);
    -  761   +  769  56
                                 if (key.contains("description")) {
    +  770  0
                                     addDescription(dependency, value, "manifest", key);
    +  771  
                                 } else {
    -  762  7
                                     productEvidence.addEvidence(source, key, value, Confidence.LOW);
    -  763  7
                                     vendorEvidence.addEvidence(source, key, value, Confidence.LOW);
    -  764  7
                                     addMatchingValues(classInformation, value, vendorEvidence);
    -  765  7
                                     addMatchingValues(classInformation, value, productEvidence);
    -  766  7
                                     if (value.matches(".*\\d.*")) {
    -  767  3
                                         final StringTokenizer tokenizer = new StringTokenizer(value, " ");
    -  768  15
                                         while (tokenizer.hasMoreElements()) {
    -  769  12
                                             final String s = tokenizer.nextToken();
    -  770  12
                                             if (s.matches("^[0-9.]+$")) {
    -  771  1
                                                 versionEvidence.addEvidence(source, key, s, Confidence.LOW);
    -  772   +  772  56
                                     productEvidence.addEvidence(source, key, value, Confidence.LOW);
    +  773  56
                                     vendorEvidence.addEvidence(source, key, value, Confidence.LOW);
    +  774  56
                                     addMatchingValues(classInformation, value, vendorEvidence);
    +  775  56
                                     addMatchingValues(classInformation, value, productEvidence);
    +  776  56
                                     if (value.matches(".*\\d.*")) {
    +  777  24
                                         final StringTokenizer tokenizer = new StringTokenizer(value, " ");
    +  778  120
                                         while (tokenizer.hasMoreElements()) {
    +  779  96
                                             final String s = tokenizer.nextToken();
    +  780  96
                                             if (s.matches("^[0-9.]+$")) {
    +  781  8
                                                 versionEvidence.addEvidence(source, key, s, Confidence.LOW);
    +  782  
                                             }
    -  773  12
                                         }
    -  774   -
                                     }
    -  775   -
                                 }
    -  776   -
                             }
    -  777   -
                         }
    -  778   -
                     }
    -  779  63
                 }
    -  780   -
             } finally {
    -  781  5
                 if (jar != null) {
    -  782  5
                     jar.close();
    -  783   -
                 }
    +  783  96
                                         }
     784   -
             }
    -  785  5
             return foundSomething;
    +
                                     }
    +  785   +
                                 }
     786   -
         }
    +
                             }
     787   -
     
    +
                         }
     788   -
         /**
    -  789   -
          * Adds a description to the given dependency. If the description contains one of the following strings beyond 100 characters,
    -  790   -
          * then the description used will be trimmed to that position:
    -  791   -
          * <ul><li>"such as"</li><li>"like "</li><li>"will use "</li><li>"* uses "</li></ul>
    -  792   -
          *
    +
                     }
    +  789  504
                 }
    +  790  40
                 if (specificationVersion != null && !hasImplementationVersion) {
    +  791  0
                     foundSomething = true;
    +  792  0
                     versionEvidence.addEvidence(source, "specificationn-version", specificationVersion, Confidence.HIGH);
     793   -
          * @param dependency a dependency
    +
                 }
     794   -
          * @param description the description
    -  795   -
          * @param source the source of the evidence
    -  796   -
          * @param key the "name" of the evidence
    +
             } finally {
    +  795  40
                 if (jar != null) {
    +  796  40
                     jar.close();
     797   -
          * @return if the description is trimmed, the trimmed version is returned; otherwise the original description is returned
    +
                 }
     798   -
          */
    -  799   -
         public static String addDescription(Dependency dependency, String description, String source, String key) {
    -  800  9
             if (dependency.getDescription() == null) {
    -  801  9
                 dependency.setDescription(description);
    -  802  
             }
    -  803   -
             String desc;
    -  804  9
             if (HTML_DETECTION_PATTERN.matcher(description).find()) {
    -  805  0
                 desc = Jsoup.parse(description).text();
    -  806   -
             } else {
    -  807  9
                 desc = description;
    -  808   -
             }
    -  809  9
             dependency.setDescription(desc);
    -  810  9
             if (desc.length() > 100) {
    -  811  0
                 desc = desc.replaceAll("\\s\\s+", " ");
    -  812  0
                 final int posSuchAs = desc.toLowerCase().indexOf("such as ", 100);
    -  813  0
                 final int posLike = desc.toLowerCase().indexOf("like ", 100);
    -  814  0
                 final int posWillUse = desc.toLowerCase().indexOf("will use ", 100);
    -  815  0
                 final int posUses = desc.toLowerCase().indexOf(" uses ", 100);
    -  816  0
                 int pos = -1;
    -  817  0
                 pos = Math.max(pos, posSuchAs);
    -  818  0
                 if (pos >= 0 && posLike >= 0) {
    -  819  0
                     pos = Math.min(pos, posLike);
    -  820   -
                 } else {
    -  821  0
                     pos = Math.max(pos, posLike);
    -  822   -
                 }
    -  823  0
                 if (pos >= 0 && posWillUse >= 0) {
    -  824  0
                     pos = Math.min(pos, posWillUse);
    -  825   -
                 } else {
    -  826  0
                     pos = Math.max(pos, posWillUse);
    -  827   -
                 }
    -  828  0
                 if (pos >= 0 && posUses >= 0) {
    -  829  0
                     pos = Math.min(pos, posUses);
    -  830   -
                 } else {
    -  831  0
                     pos = Math.max(pos, posUses);
    -  832   -
                 }
    -  833   -
     
    -  834  0
                 if (pos > 0) {
    -  835  0
                     final StringBuilder sb = new StringBuilder(pos + 3);
    -  836  0
                     sb.append(desc.substring(0, pos));
    -  837  0
                     sb.append("...");
    -  838  0
                     desc = sb.toString();
    -  839   -
                 }
    -  840  0
                 dependency.getProductEvidence().addEvidence(source, key, desc, Confidence.LOW);
    -  841  0
                 dependency.getVendorEvidence().addEvidence(source, key, desc, Confidence.LOW);
    -  842  0
             } else {
    -  843  9
                 dependency.getProductEvidence().addEvidence(source, key, desc, Confidence.MEDIUM);
    -  844  9
                 dependency.getVendorEvidence().addEvidence(source, key, desc, Confidence.MEDIUM);
    -  845   -
             }
    -  846  9
             return desc;
    -  847   +  799  40
             return foundSomething;
    +  800  
         }
    -  848   +  801  
     
    -  849   +  802  
         /**
    -  850   -
          * Adds a license to the given dependency.
    -  851   +  803   +
          * Adds a description to the given dependency. If the description contains one of the following strings beyond 100 characters,
    +  804   +
          * then the description used will be trimmed to that position:
    +  805   +
          * <ul><li>"such as"</li><li>"like "</li><li>"will use "</li><li>"* uses "</li></ul>
    +  806  
          *
    -  852   -
          * @param d a dependency
    -  853   -
          * @param license the license
    -  854   +  807   +
          * @param dependency a dependency
    +  808   +
          * @param description the description
    +  809   +
          * @param source the source of the evidence
    +  810   +
          * @param key the "name" of the evidence
    +  811   +
          * @return if the description is trimmed, the trimmed version is returned; otherwise the original description is returned
    +  812  
          */
    -  855   -
         private void addLicense(Dependency d, String license) {
    -  856  2
             if (d.getLicense() == null) {
    -  857  2
                 d.setLicense(license);
    -  858  0
             } else if (!d.getLicense().contains(license)) {
    -  859  0
                 d.setLicense(d.getLicense() + NEWLINE + license);
    -  860   +  813   +
         public static String addDescription(Dependency dependency, String description, String source, String key) {
    +  814  72
             if (dependency.getDescription() == null) {
    +  815  72
                 dependency.setDescription(description);
    +  816  
             }
    -  861  2
         }
    +  817   +
             String desc;
    +  818  72
             if (HTML_DETECTION_PATTERN.matcher(description).find()) {
    +  819  0
                 desc = Jsoup.parse(description).text();
    +  820   +
             } else {
    +  821  72
                 desc = description;
    +  822   +
             }
    +  823  72
             dependency.setDescription(desc);
    +  824  72
             if (desc.length() > 100) {
    +  825  0
                 desc = desc.replaceAll("\\s\\s+", " ");
    +  826  0
                 final int posSuchAs = desc.toLowerCase().indexOf("such as ", 100);
    +  827  0
                 final int posLike = desc.toLowerCase().indexOf("like ", 100);
    +  828  0
                 final int posWillUse = desc.toLowerCase().indexOf("will use ", 100);
    +  829  0
                 final int posUses = desc.toLowerCase().indexOf(" uses ", 100);
    +  830  0
                 int pos = -1;
    +  831  0
                 pos = Math.max(pos, posSuchAs);
    +  832  0
                 if (pos >= 0 && posLike >= 0) {
    +  833  0
                     pos = Math.min(pos, posLike);
    +  834   +
                 } else {
    +  835  0
                     pos = Math.max(pos, posLike);
    +  836   +
                 }
    +  837  0
                 if (pos >= 0 && posWillUse >= 0) {
    +  838  0
                     pos = Math.min(pos, posWillUse);
    +  839   +
                 } else {
    +  840  0
                     pos = Math.max(pos, posWillUse);
    +  841   +
                 }
    +  842  0
                 if (pos >= 0 && posUses >= 0) {
    +  843  0
                     pos = Math.min(pos, posUses);
    +  844   +
                 } else {
    +  845  0
                     pos = Math.max(pos, posUses);
    +  846   +
                 }
    +  847   +
     
    +  848  0
                 if (pos > 0) {
    +  849  0
                     final StringBuilder sb = new StringBuilder(pos + 3);
    +  850  0
                     sb.append(desc.substring(0, pos));
    +  851  0
                     sb.append("...");
    +  852  0
                     desc = sb.toString();
    +  853   +
                 }
    +  854  0
                 dependency.getProductEvidence().addEvidence(source, key, desc, Confidence.LOW);
    +  855  0
                 dependency.getVendorEvidence().addEvidence(source, key, desc, Confidence.LOW);
    +  856  0
             } else {
    +  857  72
                 dependency.getProductEvidence().addEvidence(source, key, desc, Confidence.MEDIUM);
    +  858  72
                 dependency.getVendorEvidence().addEvidence(source, key, desc, Confidence.MEDIUM);
    +  859   +
             }
    +  860  72
             return desc;
    +  861   +
         }
     862  
     
     863  
         /**
     864   -
          * The parent directory for the individual directories per archive.
    +
          * Adds a license to the given dependency.
     865   -
          */
    -  866  6
         private File tempFileLocation = null;
    +
          *
    +  866   +
          * @param d a dependency
     867   -
     
    +
          * @param license the license
     868   -
         /**
    +
          */
     869   -
          * Initializes the JarAnalyzer.
    -  870   -
          *
    -  871   -
          * @throws Exception is thrown if there is an exception creating a temporary directory
    -  872   -
          */
    -  873   -
         @Override
    +
         private void addLicense(Dependency d, String license) {
    +  870  16
             if (d.getLicense() == null) {
    +  871  16
                 d.setLicense(license);
    +  872  0
             } else if (!d.getLicense().contains(license)) {
    +  873  0
                 d.setLicense(d.getLicense() + NEWLINE + license);
     874   -
         public void initializeFileTypeAnalyzer() throws Exception {
    -  875  1
             final File baseDir = Settings.getTempDirectory();
    -  876  1
             tempFileLocation = File.createTempFile("check", "tmp", baseDir);
    -  877  1
             if (!tempFileLocation.delete()) {
    -  878  0
                 final String msg = String.format("Unable to delete temporary file '%s'.", tempFileLocation.getAbsolutePath());
    -  879  0
                 throw new AnalysisException(msg);
    -  880  
             }
    -  881  1
             if (!tempFileLocation.mkdirs()) {
    -  882  0
                 final String msg = String.format("Unable to create directory '%s'.", tempFileLocation.getAbsolutePath());
    -  883  0
                 throw new AnalysisException(msg);
    +  875  16
         }
    +  876   +
     
    +  877   +
         /**
    +  878   +
          * The parent directory for the individual directories per archive.
    +  879   +
          */
    +  880  48
         private File tempFileLocation = null;
    +  881   +
     
    +  882   +
         /**
    +  883   +
          * Initializes the JarAnalyzer.
     884   -
             }
    -  885  1
         }
    -  886   -
     
    -  887   -
         /**
    -  888   -
          * Deletes any files extracted from the JAR during analysis.
    -  889   -
          */
    -  890   -
         @Override
    -  891   -
         public void close() {
    -  892  1
             if (tempFileLocation != null && tempFileLocation.exists()) {
    -  893  1
                 LOGGER.log(Level.FINE, "Attempting to delete temporary files");
    -  894  1
                 final boolean success = FileUtils.delete(tempFileLocation);
    -  895  1
                 if (!success) {
    -  896  0
                     LOGGER.log(Level.WARNING,
    -  897   -
                             "Failed to delete some temporary files, see the log for more details");
    -  898   -
                 }
    -  899   -
             }
    -  900  1
         }
    -  901   -
     
    -  902   -
         /**
    -  903   -
          * Determines if the key value pair from the manifest is for an "import" type entry for package names.
    -  904  
          *
    -  905   -
          * @param key the key from the manifest
    -  906   -
          * @param value the value from the manifest
    -  907   -
          * @return true or false depending on if it is believed the entry is an "import" entry
    -  908   +  885   +
          * @throws Exception is thrown if there is an exception creating a temporary directory
    +  886  
          */
    -  909   -
         private boolean isImportPackage(String key, String value) {
    -  910  15
             final Pattern packageRx = Pattern.compile("^([a-zA-Z0-9_#\\$\\*\\.]+\\s*[,;]\\s*)+([a-zA-Z0-9_#\\$\\*\\.]+\\s*)?$");
    -  911  15
             final boolean matches = packageRx.matcher(value).matches();
    -  912  15
             return matches && (key.contains("import") || key.contains("include") || value.length() > 10);
    -  913   -
         }
    +  887   +
         @Override
    +  888   +
         public void initializeFileTypeAnalyzer() throws Exception {
    +  889  8
             final File baseDir = Settings.getTempDirectory();
    +  890  8
             tempFileLocation = File.createTempFile("check", "tmp", baseDir);
    +  891  8
             if (!tempFileLocation.delete()) {
    +  892  0
                 final String msg = String.format("Unable to delete temporary file '%s'.", tempFileLocation.getAbsolutePath());
    +  893  0
                 throw new AnalysisException(msg);
    +  894   +
             }
    +  895  8
             if (!tempFileLocation.mkdirs()) {
    +  896  0
                 final String msg = String.format("Unable to create directory '%s'.", tempFileLocation.getAbsolutePath());
    +  897  0
                 throw new AnalysisException(msg);
    +  898   +
             }
    +  899  8
         }
    +  900   +
     
    +  901   +
         /**
    +  902   +
          * Deletes any files extracted from the JAR during analysis.
    +  903   +
          */
    +  904   +
         @Override
    +  905   +
         public void close() {
    +  906  8
             if (tempFileLocation != null && tempFileLocation.exists()) {
    +  907  8
                 LOGGER.debug("Attempting to delete temporary files");
    +  908  8
                 final boolean success = FileUtils.delete(tempFileLocation);
    +  909  8
                 if (!success) {
    +  910  0
                     LOGGER.warn("Failed to delete some temporary files, see the log for more details");
    +  911   +
                 }
    +  912   +
             }
    +  913  8
         }
     914  
     
     915  
         /**
     916   -
          * Cycles through an enumeration of JarEntries, contained within the dependency, and returns a list of the class names. This
    +
          * Determines if the key value pair from the manifest is for an "import" type entry for package names.
     917   -
          * does not include core Java package names (i.e. java.* or javax.*).
    -  918  
          *
    +  918   +
          * @param key the key from the manifest
     919   -
          * @param dependency the dependency being analyzed
    +
          * @param value the value from the manifest
     920   -
          * @return an list of fully qualified class names
    +
          * @return true or false depending on if it is believed the entry is an "import" entry
     921  
          */
     922   -
         private List<ClassNameInformation> collectClassNames(Dependency dependency) {
    -  923  5
             final List<ClassNameInformation> classNames = new ArrayList<ClassNameInformation>();
    -  924  5
             JarFile jar = null;
    -  925   -
             try {
    -  926  5
                 jar = new JarFile(dependency.getActualFilePath());
    -  927  5
                 final Enumeration entries = jar.entries();
    -  928  1848
                 while (entries.hasMoreElements()) {
    -  929  1843
                     final JarEntry entry = (JarEntry) entries.nextElement();
    -  930  1843
                     final String name = entry.getName().toLowerCase();
    -  931   -
                     //no longer stripping "|com\\.sun" - there are some com.sun jar files with CVEs.
    -  932  1843
                     if (name.endsWith(".class") && !name.matches("^javax?\\..*$")) {
    -  933  1535
                         final ClassNameInformation className = new ClassNameInformation(name.substring(0, name.length() - 6));
    -  934  1535
                         classNames.add(className);
    -  935   -
                     }
    -  936  1843
                 }
    -  937  0
             } catch (IOException ex) {
    -  938  0
                 final String msg = String.format("Unable to open jar file '%s'.", dependency.getFileName());
    -  939  0
                 LOGGER.log(Level.WARNING, msg);
    -  940  0
                 LOGGER.log(Level.FINE, null, ex);
    -  941   -
             } finally {
    -  942  5
                 if (jar != null) {
    -  943   -
                     try {
    -  944  5
                         jar.close();
    -  945  0
                     } catch (IOException ex) {
    -  946  0
                         LOGGER.log(Level.FINEST, null, ex);
    -  947  5
                     }
    -  948   -
                 }
    -  949   -
             }
    -  950  5
             return classNames;
    -  951   +
         private boolean isImportPackage(String key, String value) {
    +  923  112
             final Pattern packageRx = Pattern.compile("^([a-zA-Z0-9_#\\$\\*\\.]+\\s*[,;]\\s*)+([a-zA-Z0-9_#\\$\\*\\.]+\\s*)?$");
    +  924  112
             final boolean matches = packageRx.matcher(value).matches();
    +  925  112
             return matches && (key.contains("import") || key.contains("include") || value.length() > 10);
    +  926  
         }
    -  952   +  927  
     
    -  953   +  928  
         /**
    -  954   -
          * Cycles through the list of class names and places the package levels 0-3 into the provided maps for vendor and product.
    -  955   -
          * This is helpful when analyzing vendor/product as many times this is included in the package name.
    -  956   +  929   +
          * Cycles through an enumeration of JarEntries, contained within the dependency, and returns a list of the class names. This
    +  930   +
          * does not include core Java package names (i.e. java.* or javax.*).
    +  931  
          *
    -  957   -
          * @param classNames a list of class names
    -  958   -
          * @param vendor HashMap of possible vendor names from package names (e.g. owasp)
    -  959   -
          * @param product HashMap of possible product names from package names (e.g. dependencycheck)
    -  960   +  932   +
          * @param dependency the dependency being analyzed
    +  933   +
          * @return an list of fully qualified class names
    +  934  
          */
    +  935   +
         private List<ClassNameInformation> collectClassNames(Dependency dependency) {
    +  936  40
             final List<ClassNameInformation> classNames = new ArrayList<ClassNameInformation>();
    +  937  40
             JarFile jar = null;
    +  938   +
             try {
    +  939  40
                 jar = new JarFile(dependency.getActualFilePath());
    +  940  40
                 final Enumeration<JarEntry> entries = jar.entries();
    +  941  14784
                 while (entries.hasMoreElements()) {
    +  942  14744
                     final JarEntry entry = entries.nextElement();
    +  943  14744
                     final String name = entry.getName().toLowerCase();
    +  944   +
                     //no longer stripping "|com\\.sun" - there are some com.sun jar files with CVEs.
    +  945  14744
                     if (name.endsWith(".class") && !name.matches("^javax?\\..*$")) {
    +  946  12280
                         final ClassNameInformation className = new ClassNameInformation(name.substring(0, name.length() - 6));
    +  947  12280
                         classNames.add(className);
    +  948   +
                     }
    +  949  14744
                 }
    +  950  0
             } catch (IOException ex) {
    +  951  0
                 LOGGER.warn("Unable to open jar file '{}'.", dependency.getFileName());
    +  952  0
                 LOGGER.debug("", ex);
    +  953   +
             } finally {
    +  954  40
                 if (jar != null) {
    +  955   +
                     try {
    +  956  40
                         jar.close();
    +  957  0
                     } catch (IOException ex) {
    +  958  0
                         LOGGER.trace("", ex);
    +  959  40
                     }
    +  960   +
                 }
     961   -
         private void analyzeFullyQualifiedClassNames(List<ClassNameInformation> classNames,
    -  962   -
                 Map<String, Integer> vendor, Map<String, Integer> product) {
    -  963  5
             for (ClassNameInformation entry : classNames) {
    -  964  1535
                 final List<String> list = entry.getPackageStructure();
    -  965  1535
                 addEntry(vendor, list.get(0));
    -  966   +
             }
    +  962  40
             return classNames;
    +  963   +
         }
    +  964  
     
    -  967  1535
                 if (list.size() == 2) {
    -  968  0
                     addEntry(product, list.get(1));
    +  965   +
         /**
    +  966   +
          * Cycles through the list of class names and places the package levels 0-3 into the provided maps for vendor and product.
    +  967   +
          * This is helpful when analyzing vendor/product as many times this is included in the package name.
    +  968   +
          *
     969   -
                 }
    -  970  1535
                 if (list.size() == 3) {
    -  971  345
                     addEntry(vendor, list.get(1));
    -  972  345
                     addEntry(product, list.get(1));
    -  973  345
                     addEntry(product, list.get(2));
    +
          * @param classNames a list of class names
    +  970   +
          * @param vendor HashMap of possible vendor names from package names (e.g. owasp)
    +  971   +
          * @param product HashMap of possible product names from package names (e.g. dependencycheck)
    +  972   +
          */
    +  973   +
         private void analyzeFullyQualifiedClassNames(List<ClassNameInformation> classNames,
     974   -
                 }
    -  975  1535
                 if (list.size() >= 4) {
    -  976  1190
                     addEntry(vendor, list.get(1));
    -  977  1190
                     addEntry(vendor, list.get(2));
    -  978  1190
                     addEntry(product, list.get(1));
    -  979  1190
                     addEntry(product, list.get(2));
    -  980  1190
                     addEntry(product, list.get(3));
    +
                 Map<String, Integer> vendor, Map<String, Integer> product) {
    +  975  40
             for (ClassNameInformation entry : classNames) {
    +  976  12280
                 final List<String> list = entry.getPackageStructure();
    +  977  12280
                 addEntry(vendor, list.get(0));
    +  978   +
     
    +  979  12280
                 if (list.size() == 2) {
    +  980  0
                     addEntry(product, list.get(1));
     981  
                 }
    -  982  1535
             }
    -  983  5
         }
    -  984   -
     
    -  985   -
         /**
    +  982  12280
                 if (list.size() == 3) {
    +  983  2760
                     addEntry(vendor, list.get(1));
    +  984  2760
                     addEntry(product, list.get(1));
    +  985  2760
                     addEntry(product, list.get(2));
     986   -
          * Adds an entry to the specified collection and sets the Integer (e.g. the count) to 1. If the entry already exists in the
    -  987   -
          * collection then the Integer is incremented by 1.
    -  988   -
          *
    -  989   -
          * @param collection a collection of strings and their occurrence count
    -  990   -
          * @param key the key to add to the collection
    -  991   -
          */
    -  992   -
         private void addEntry(Map<String, Integer> collection, String key) {
    -  993  8520
             if (collection.containsKey(key)) {
    -  994  7487
                 collection.put(key, collection.get(key) + 1);
    -  995   -
             } else {
    -  996  1033
                 collection.put(key, 1);
    +
                 }
    +  987  12280
                 if (list.size() >= 4) {
    +  988  9520
                     addEntry(vendor, list.get(1));
    +  989  9520
                     addEntry(vendor, list.get(2));
    +  990  9520
                     addEntry(product, list.get(1));
    +  991  9520
                     addEntry(product, list.get(2));
    +  992  9520
                     addEntry(product, list.get(3));
    +  993   +
                 }
    +  994  12280
             }
    +  995  40
         }
    +  996   +
     
     997   -
             }
    -  998  8520
         }
    +
         /**
    +  998   +
          * Adds an entry to the specified collection and sets the Integer (e.g. the count) to 1. If the entry already exists in the
     999   -
     
    +
          * collection then the Integer is incremented by 1.
     1000   -
         /**
    +
          *
     1001   -
          * Cycles through the collection of class name information to see if parts of the package names are contained in the provided
    +
          * @param collection a collection of strings and their occurrence count
     1002   -
          * value. If found, it will be added as the HIGHEST confidence evidence because we have more then one source corroborating the
    +
          * @param key the key to add to the collection
     1003   -
          * value.
    +
          */
     1004   -
          *
    -  1005   -
          * @param classes a collection of class name information
    -  1006   -
          * @param value the value to check to see if it contains a package name
    +
         private void addEntry(Map<String, Integer> collection, String key) {
    +  1005  68160
             if (collection.containsKey(key)) {
    +  1006  59896
                 collection.put(key, collection.get(key) + 1);
     1007   -
          * @param evidence the evidence collection to add new entries too
    -  1008   -
          */
    +
             } else {
    +  1008  8264
                 collection.put(key, 1);
     1009   -
         private static void addMatchingValues(List<ClassNameInformation> classes, String value, EvidenceCollection evidence) {
    -  1010  41
             if (value == null || value.isEmpty() || classes == null || classes.isEmpty()) {
    -  1011  0
                 return;
    -  1012  
             }
    -  1013  41
             final String text = value.toLowerCase();
    -  1014  41
             for (ClassNameInformation cni : classes) {
    -  1015  16500
                 for (String key : cni.getPackageStructure()) {
    -  1016  63820
                     if (text.contains(key)) { //note, package structure elements are already lowercase.
    -  1017  15400
                         evidence.addEvidence("jar", "package name", key, Confidence.HIGHEST);
    -  1018   -
                     }
    -  1019  63820
                 }
    -  1020  16500
             }
    -  1021  41
         }
    -  1022   +  1010  68160
         }
    +  1011  
     
    -  1023   +  1012  
         /**
    -  1024   -
          * Simple check to see if the attribute from a manifest is just a package name.
    -  1025   +  1013   +
          * Cycles through the collection of class name information to see if parts of the package names are contained in the provided
    +  1014   +
          * value. If found, it will be added as the HIGHEST confidence evidence because we have more then one source corroborating the
    +  1015   +
          * value.
    +  1016  
          *
    -  1026   -
          * @param key the key of the value to check
    -  1027   -
          * @param value the value to check
    -  1028   -
          * @return true if the value looks like a java package name, otherwise false
    -  1029   +  1017   +
          * @param classes a collection of class name information
    +  1018   +
          * @param value the value to check to see if it contains a package name
    +  1019   +
          * @param evidence the evidence collection to add new entries too
    +  1020  
          */
    +  1021   +
         private static void addMatchingValues(List<ClassNameInformation> classes, String value, EvidenceCollection evidence) {
    +  1022  304
             if (value == null || value.isEmpty() || classes == null || classes.isEmpty()) {
    +  1023  0
                 return;
    +  1024   +
             }
    +  1025  304
             final String text = value.toLowerCase();
    +  1026  304
             for (ClassNameInformation cni : classes) {
    +  1027  122096
                 for (String key : cni.getPackageStructure()) {
    +  1028  472048
                     if (text.contains(key)) { //note, package structure elements are already lowercase.
    +  1029  115512
                         evidence.addEvidence("jar", "package name", key, Confidence.HIGHEST);
     1030   -
         private boolean isPackage(String key, String value) {
    -  1031   -
     
    -  1032  15
             return !key.matches(".*(version|title|vendor|name|license|description).*")
    -  1033   -
                     && value.matches("^([a-zA-Z_][a-zA-Z0-9_\\$]*(\\.[a-zA-Z_][a-zA-Z0-9_\\$]*)*)?$");
    +
                     }
    +  1031  472048
                 }
    +  1032  122096
             }
    +  1033  304
         }
     1034  
     
     1035   -
         }
    +
         /**
     1036   -
     
    +
          * Simple check to see if the attribute from a manifest is just a package name.
     1037   -
         /**
    +
          *
     1038   -
          * Extracts the license information from the pom and adds it to the dependency.
    +
          * @param key the key of the value to check
     1039   -
          *
    +
          * @param value the value to check
     1040   -
          * @param pom the pom object
    +
          * @return true if the value looks like a java package name, otherwise false
     1041   -
          * @param dependency the dependency to add license information too
    +
          */
     1042   -
          */
    +
         private boolean isPackage(String key, String value) {
     1043   -
         public static void extractLicense(Model pom, Dependency dependency) {
    -  1044   -
             //license
    -  1045  1
             if (pom.getLicenses() != null) {
    -  1046  1
                 String license = null;
    -  1047  1
                 for (License lic : pom.getLicenses()) {
    -  1048  0
                     String tmp = null;
    -  1049  0
                     if (lic.getName() != null) {
    -  1050  0
                         tmp = lic.getName();
    +
     
    +  1044  112
             return !key.matches(".*(version|title|vendor|name|license|description).*")
    +  1045   +
                     && value.matches("^([a-zA-Z_][a-zA-Z0-9_\\$]*(\\.[a-zA-Z_][a-zA-Z0-9_\\$]*)*)?$");
    +  1046   +
     
    +  1047   +
         }
    +  1048   +
     
    +  1049   +
         /**
    +  1050   +
          * Extracts the license information from the pom and adds it to the dependency.
     1051   -
                     }
    -  1052  0
                     if (lic.getUrl() != null) {
    -  1053  0
                         if (tmp == null) {
    -  1054  0
                             tmp = lic.getUrl();
    -  1055   -
                         } else {
    -  1056  0
                             tmp += ": " + lic.getUrl();
    -  1057   -
                         }
    -  1058   -
                     }
    -  1059  0
                     if (tmp == null) {
    -  1060  0
                         continue;
    -  1061   -
                     }
    -  1062  0
                     if (HTML_DETECTION_PATTERN.matcher(tmp).find()) {
    -  1063  0
                         tmp = Jsoup.parse(tmp).text();
    -  1064   -
                     }
    -  1065  0
                     if (license == null) {
    -  1066  0
                         license = tmp;
    -  1067   -
                     } else {
    -  1068  0
                         license += "\n" + tmp;
    -  1069   -
                     }
    -  1070  0
                 }
    -  1071  1
                 if (license != null) {
    -  1072  0
                     dependency.setLicense(license);
    -  1073   -
     
    -  1074   -
                 }
    -  1075   -
             }
    -  1076  1
         }
    -  1077   -
     
    -  1078   -
         /**
    -  1079   -
          * Stores information about a class name.
    -  1080   -
          */
    -  1081   -
         protected static class ClassNameInformation {
    -  1082   -
     
    -  1083   -
             /**
    -  1084   -
              * <p>
    -  1085   -
              * Stores information about a given class name. This class will keep the fully qualified class name and a list of the
    -  1086   -
              * important parts of the package structure. Up to the first four levels of the package structure are stored, excluding a
    -  1087   -
              * leading "org" or "com". Example:</p>
    -  1088   -
              * <code>ClassNameInformation obj = new ClassNameInformation("org.owasp.dependencycheck.analyzer.JarAnalyzer");
    -  1089   -
              * System.out.println(obj.getName());
    -  1090   -
              * for (String p : obj.getPackageStructure())
    -  1091   -
              *     System.out.println(p);
    -  1092   -
              * </code>
    -  1093   -
              * <p>
    -  1094   -
              * Would result in:</p>
    -  1095   -
              * <code>org.owasp.dependencycheck.analyzer.JarAnalyzer
    -  1096   -
              * owasp
    -  1097   -
              * dependencycheck
    -  1098   -
              * analyzer
    -  1099   -
              * jaranalyzer</code>
    -  1100   -
              *
    -  1101   -
              * @param className a fully qualified class name
    -  1102   -
              */
    -  1103  1535
             ClassNameInformation(String className) {
    -  1104  1535
                 name = className;
    -  1105  1535
                 if (name.contains("/")) {
    -  1106  1535
                     final String[] tmp = className.toLowerCase().split("/");
    -  1107  1535
                     int start = 0;
    -  1108  1535
                     int end = 3;
    -  1109  1535
                     if ("com".equals(tmp[0]) || "org".equals(tmp[0])) {
    -  1110  1535
                         start = 1;
    -  1111  1535
                         end = 4;
    -  1112   -
                     }
    -  1113  1535
                     if (tmp.length <= end) {
    -  1114  345
                         end = tmp.length - 1;
    -  1115   -
                     }
    -  1116  7330
                     for (int i = start; i <= end; i++) {
    -  1117  5795
                         packageStructure.add(tmp[i]);
    -  1118   -
                     }
    -  1119  1535
                 } else {
    -  1120  0
                     packageStructure.add(name);
    -  1121   -
                 }
    -  1122  1535
             }
    -  1123   -
             /**
    -  1124   -
              * The fully qualified class name.
    -  1125   -
              */
    -  1126   -
             private String name;
    -  1127   -
     
    -  1128   -
             /**
    -  1129   -
              * Get the value of name
    -  1130   -
              *
    -  1131   -
              * @return the value of name
    -  1132   -
              */
    -  1133   -
             public String getName() {
    -  1134  0
                 return name;
    -  1135   -
             }
    -  1136   -
     
    -  1137   -
             /**
    -  1138   -
              * Set the value of name
    -  1139   -
              *
    -  1140   -
              * @param name new value of name
    -  1141   -
              */
    -  1142   -
             public void setName(String name) {
    -  1143  0
                 this.name = name;
    -  1144  0
             }
    -  1145   -
             /**
    -  1146   -
              * Up to the first four levels of the package structure, excluding a leading "org" or "com".
    -  1147   -
              */
    -  1148  1535
             private final ArrayList<String> packageStructure = new ArrayList<String>();
    -  1149   -
     
    -  1150   -
             /**
    -  1151   -
              * Get the value of packageStructure
    -  1152   -
              *
    -  1153   -
              * @return the value of packageStructure
    -  1154   -
              */
    -  1155   -
             public ArrayList<String> getPackageStructure() {
    -  1156  18035
                 return packageStructure;
    -  1157   -
             }
    -  1158   -
         }
    -  1159   -
     
    -  1160   -
         /**
    -  1161   -
          * Retrieves the next temporary directory to extract an archive too.
    -  1162  
          *
    -  1163   -
          * @return a directory
    -  1164   -
          * @throws AnalysisException thrown if unable to create temporary directory
    -  1165   +  1052   +
          * @param pom the pom object
    +  1053   +
          * @param dependency the dependency to add license information too
    +  1054  
          */
    +  1055   +
         public static void extractLicense(Model pom, Dependency dependency) {
    +  1056   +
             //license
    +  1057  8
             if (pom.getLicenses() != null) {
    +  1058  8
                 String license = null;
    +  1059  8
                 for (License lic : pom.getLicenses()) {
    +  1060  0
                     String tmp = null;
    +  1061  0
                     if (lic.getName() != null) {
    +  1062  0
                         tmp = lic.getName();
    +  1063   +
                     }
    +  1064  0
                     if (lic.getUrl() != null) {
    +  1065  0
                         if (tmp == null) {
    +  1066  0
                             tmp = lic.getUrl();
    +  1067   +
                         } else {
    +  1068  0
                             tmp += ": " + lic.getUrl();
    +  1069   +
                         }
    +  1070   +
                     }
    +  1071  0
                     if (tmp == null) {
    +  1072  0
                         continue;
    +  1073   +
                     }
    +  1074  0
                     if (HTML_DETECTION_PATTERN.matcher(tmp).find()) {
    +  1075  0
                         tmp = Jsoup.parse(tmp).text();
    +  1076   +
                     }
    +  1077  0
                     if (license == null) {
    +  1078  0
                         license = tmp;
    +  1079   +
                     } else {
    +  1080  0
                         license += "\n" + tmp;
    +  1081   +
                     }
    +  1082  0
                 }
    +  1083  8
                 if (license != null) {
    +  1084  0
                     dependency.setLicense(license);
    +  1085   +
     
    +  1086   +
                 }
    +  1087   +
             }
    +  1088  8
         }
    +  1089   +
     
    +  1090   +
         /**
    +  1091   +
          * Stores information about a class name.
    +  1092   +
          */
    +  1093   +
         protected static class ClassNameInformation {
    +  1094   +
     
    +  1095   +
             /**
    +  1096   +
              * <p>
    +  1097   +
              * Stores information about a given class name. This class will keep the fully qualified class name and a list of the
    +  1098   +
              * important parts of the package structure. Up to the first four levels of the package structure are stored, excluding a
    +  1099   +
              * leading "org" or "com". Example:</p>
    +  1100   +
              * <code>ClassNameInformation obj = new ClassNameInformation("org.owasp.dependencycheck.analyzer.JarAnalyzer");
    +  1101   +
              * System.out.println(obj.getName());
    +  1102   +
              * for (String p : obj.getPackageStructure())
    +  1103   +
              *     System.out.println(p);
    +  1104   +
              * </code>
    +  1105   +
              * <p>
    +  1106   +
              * Would result in:</p>
    +  1107   +
              * <code>org.owasp.dependencycheck.analyzer.JarAnalyzer
    +  1108   +
              * owasp
    +  1109   +
              * dependencycheck
    +  1110   +
              * analyzer
    +  1111   +
              * jaranalyzer</code>
    +  1112   +
              *
    +  1113   +
              * @param className a fully qualified class name
    +  1114   +
              */
    +  1115  12280
             ClassNameInformation(String className) {
    +  1116  12280
                 name = className;
    +  1117  12280
                 if (name.contains("/")) {
    +  1118  12280
                     final String[] tmp = className.toLowerCase().split("/");
    +  1119  12280
                     int start = 0;
    +  1120  12280
                     int end = 3;
    +  1121  12280
                     if ("com".equals(tmp[0]) || "org".equals(tmp[0])) {
    +  1122  12280
                         start = 1;
    +  1123  12280
                         end = 4;
    +  1124   +
                     }
    +  1125  12280
                     if (tmp.length <= end) {
    +  1126  2760
                         end = tmp.length - 1;
    +  1127   +
                     }
    +  1128  58640
                     for (int i = start; i <= end; i++) {
    +  1129  46360
                         packageStructure.add(tmp[i]);
    +  1130   +
                     }
    +  1131  12280
                 } else {
    +  1132  0
                     packageStructure.add(name);
    +  1133   +
                 }
    +  1134  12280
             }
    +  1135   +
             /**
    +  1136   +
              * The fully qualified class name.
    +  1137   +
              */
    +  1138   +
             private String name;
    +  1139   +
     
    +  1140   +
             /**
    +  1141   +
              * Get the value of name
    +  1142   +
              *
    +  1143   +
              * @return the value of name
    +  1144   +
              */
    +  1145   +
             public String getName() {
    +  1146  0
                 return name;
    +  1147   +
             }
    +  1148   +
     
    +  1149   +
             /**
    +  1150   +
              * Set the value of name
    +  1151   +
              *
    +  1152   +
              * @param name new value of name
    +  1153   +
              */
    +  1154   +
             public void setName(String name) {
    +  1155  0
                 this.name = name;
    +  1156  0
             }
    +  1157   +
             /**
    +  1158   +
              * Up to the first four levels of the package structure, excluding a leading "org" or "com".
    +  1159   +
              */
    +  1160  12280
             private final ArrayList<String> packageStructure = new ArrayList<String>();
    +  1161   +
     
    +  1162   +
             /**
    +  1163   +
              * Get the value of packageStructure
    +  1164   +
              *
    +  1165   +
              * @return the value of packageStructure
     1166   -
         private File getNextTempDirectory() throws AnalysisException {
    -  1167  0
             dirCount += 1;
    -  1168  0
             final File directory = new File(tempFileLocation, String.valueOf(dirCount));
    +
              */
    +  1167   +
             public ArrayList<String> getPackageStructure() {
    +  1168  134376
                 return packageStructure;
     1169   -
             //getting an exception for some directories not being able to be created; might be because the directory already exists?
    -  1170  0
             if (directory.exists()) {
    -  1171  0
                 return getNextTempDirectory();
    -  1172  
             }
    -  1173  0
             if (!directory.mkdirs()) {
    -  1174  0
                 final String msg = String.format("Unable to create temp directory '%s'.", directory.getAbsolutePath());
    -  1175  0
                 throw new AnalysisException(msg);
    -  1176   -
             }
    -  1177  0
             return directory;
    -  1178   +  1170  
         }
    -  1179   +  1171   +
     
    +  1172   +
         /**
    +  1173   +
          * Retrieves the next temporary directory to extract an archive too.
    +  1174   +
          *
    +  1175   +
          * @return a directory
    +  1176   +
          * @throws AnalysisException thrown if unable to create temporary directory
    +  1177   +
          */
    +  1178   +
         private File getNextTempDirectory() throws AnalysisException {
    +  1179  0
             dirCount += 1;
    +  1180  0
             final File directory = new File(tempFileLocation, String.valueOf(dirCount));
    +  1181   +
             //getting an exception for some directories not being able to be created; might be because the directory already exists?
    +  1182  0
             if (directory.exists()) {
    +  1183  0
                 return getNextTempDirectory();
    +  1184   +
             }
    +  1185  0
             if (!directory.mkdirs()) {
    +  1186  0
                 final String msg = String.format("Unable to create temp directory '%s'.", directory.getAbsolutePath());
    +  1187  0
                 throw new AnalysisException(msg);
    +  1188   +
             }
    +  1189  0
             return directory;
    +  1190   +
         }
    +  1191  
     }
    - + 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 dce3811fa..1923673ba 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.NexusAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.NexusAnalyzer.html @@ -12,7 +12,7 @@
     
    - +
    Classes in this File Line Coverage Branch Coverage Complexity
    NexusAnalyzer
    18%
    13/69
    4%
    1/24
    3.375
    NexusAnalyzer
    20%
    14/67
    4%
    1/24
    3.375
     
    @@ -56,410 +56,422 @@  19  
     
     20   -
     import java.io.File;
    -  21   -
     import java.io.FileNotFoundException;
    -  22   -
     import java.io.IOException;
    -  23   -
     import java.net.MalformedURLException;
    -  24   -
     import java.net.URL;
    -  25   -
     import java.util.Set;
    -  26   -
     import java.util.logging.Level;
    -  27   -
     import java.util.logging.Logger;
    -  28  
     import org.apache.commons.io.FileUtils;
    -  29   +  21  
     import org.owasp.dependencycheck.Engine;
    -  30   +  22  
     import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
    -  31   +  23  
     import org.owasp.dependencycheck.data.nexus.MavenArtifact;
    -  32   +  24  
     import org.owasp.dependencycheck.data.nexus.NexusSearch;
    -  33   +  25  
     import org.owasp.dependencycheck.dependency.Confidence;
    -  34   +  26  
     import org.owasp.dependencycheck.dependency.Dependency;
    -  35   +  27  
     import org.owasp.dependencycheck.dependency.Evidence;
    -  36   +  28  
     import org.owasp.dependencycheck.xml.pom.PomUtils;
    +  29   +
     import org.slf4j.Logger;
    +  30   +
     import org.slf4j.LoggerFactory;
    +  31   +
     
    +  32   +
     import java.io.File;
    +  33   +
     import java.io.FileFilter;
    +  34   +
     import java.io.FileNotFoundException;
    +  35   +
     import java.io.IOException;
    +  36   +
     import java.net.MalformedURLException;
     37   -
     import org.owasp.dependencycheck.utils.InvalidSettingException;
    +
     import java.net.URL;
     38  
     import org.owasp.dependencycheck.utils.DownloadFailedException;
     39  
     import org.owasp.dependencycheck.utils.Downloader;
     40   -
     import org.owasp.dependencycheck.utils.Settings;
    +
     import org.owasp.dependencycheck.utils.FileFilterBuilder;
     41   -
     
    +
     import org.owasp.dependencycheck.utils.InvalidSettingException;
     42   -
     /**
    +
     import org.owasp.dependencycheck.utils.Settings;
     43   -
      * Analyzer which will attempt to locate a dependency on a Nexus service by SHA-1 digest of the dependency.
    +
     
     44   -
      *
    +
     /**
     45   -
      * There are two settings which govern this behavior:
    +
      * Analyzer which will attempt to locate a dependency on a Nexus service by SHA-1 digest of the dependency.
     46  
      *
     47   -
      * <ul>
    +
      * There are two settings which govern this behavior:
     48   -
      * <li>{@link org.owasp.dependencycheck.utils.Settings.KEYS#ANALYZER_NEXUS_ENABLED} determines whether this analyzer is even
    -  49   -
      * enabled. This can be overridden by setting the system property.</li>
    -  50   -
      * <li>{@link org.owasp.dependencycheck.utils.Settings.KEYS#ANALYZER_NEXUS_URL} the URL to a Nexus service to search by SHA-1.
    -  51   -
      * There is an expected <code>%s</code> in this where the SHA-1 will get entered.</li>
    -  52   -
      * </ul>
    -  53  
      *
    +  49   +
      * <ul>
    +  50   +
      * <li>{@link org.owasp.dependencycheck.utils.Settings.KEYS#ANALYZER_NEXUS_ENABLED} determines whether this analyzer is even
    +  51   +
      * enabled. This can be overridden by setting the system property.</li>
    +  52   +
      * <li>{@link org.owasp.dependencycheck.utils.Settings.KEYS#ANALYZER_NEXUS_URL} the URL to a Nexus service to search by SHA-1.
    +  53   +
      * There is an expected <code>%s</code> in this where the SHA-1 will get entered.</li>
     54   -
      * @author colezlaw
    +
      * </ul>
     55   -
      */
    -  56  2
     public class NexusAnalyzer extends AbstractFileTypeAnalyzer {
    +
      *
    +  56   +
      * @author colezlaw
     57   -
     
    -  58   -
         /**
    +
      */
    +  58  24
     public class NexusAnalyzer extends AbstractFileTypeAnalyzer {
     59   -
          * The default URL - this will be used by the CentralAnalyzer to determine whether to enable this.
    +
     
     60   -
          */
    +
         /**
     61   -
         public static final String DEFAULT_URL = "https://repository.sonatype.org/service/local/";
    +
          * The default URL - this will be used by the CentralAnalyzer to determine whether to enable this.
     62   -
     
    +
          */
     63   -
         /**
    +
         public static final String DEFAULT_URL = "https://repository.sonatype.org/service/local/";
     64   -
          * The logger.
    +
     
     65   -
          */
    -  66  1
         private static final Logger LOGGER = Logger.getLogger(NexusAnalyzer.class.getName());
    +
         /**
    +  66   +
          * The logger.
     67   -
     
    -  68   -
         /**
    +
          */
    +  68  8
         private static final Logger LOGGER = LoggerFactory.getLogger(NexusAnalyzer.class);
     69   -
          * The name of the analyzer.
    +
     
     70   -
          */
    +
         /**
     71   -
         private static final String ANALYZER_NAME = "Nexus Analyzer";
    +
          * The name of the analyzer.
     72   -
     
    +
          */
     73   -
         /**
    +
         private static final String ANALYZER_NAME = "Nexus Analyzer";
     74   -
          * The phase in which the analyzer runs.
    +
     
     75   -
          */
    -  76  1
         private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
    +
         /**
    +  76   +
          * The phase in which the analyzer runs.
     77   -
     
    -  78   -
         /**
    +
          */
    +  78  8
         private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
     79   -
          * The types of files on which this will work.
    +
     
     80   -
          */
    -  81  1
         private static final Set<String> SUPPORTED_EXTENSIONS = newHashSet("jar");
    +
         /**
    +  81   +
          * The types of files on which this will work.
     82   -
     
    +
          */
     83   -
         /**
    +
         private static final String SUPPORTED_EXTENSIONS = "jar";
     84   -
          * The Nexus Search to be set up for this analyzer.
    +
     
     85   -
          */
    +
         /**
     86   -
         private NexusSearch searcher;
    +
          * The Nexus Search to be set up for this analyzer.
     87   -
     
    +
          */
     88   -
         /**
    +
         private NexusSearch searcher;
     89   -
          * Field indicating if the analyzer is enabled.
    +
     
     90   -
          */
    -  91  2
         private final boolean enabled = checkEnabled();
    +
         /**
    +  91   +
          * Field indicating if the analyzer is enabled.
     92   -
     
    -  93   -
         /**
    +
          */
    +  93  24
         private final boolean enabled = checkEnabled();
     94   -
          * Determines if this analyzer is enabled
    +
     
     95   -
          *
    +
         /**
     96   -
          * @return <code>true</code> if the analyzer is enabled; otherwise <code>false</code>
    +
          * Determines if this analyzer is enabled
     97   -
          */
    +
          *
     98   -
         private boolean checkEnabled() {
    +
          * @return <code>true</code> if the analyzer is enabled; otherwise <code>false</code>
     99   -
             /* Enable this analyzer ONLY if the Nexus URL has been set to something
    +
          */
     100   -
              other than the default one (if it's the default one, we'll use the
    +
         private boolean checkEnabled() {
     101   -
              central one) and it's enabled by the user.
    +
             /* Enable this analyzer ONLY if the Nexus URL has been set to something
     102   -
              */
    -  103  2
             boolean retval = false;
    +
              other than the default one (if it's the default one, we'll use the
    +  103   +
              central one) and it's enabled by the user.
     104   -
             try {
    -  105  2
                 if ((!DEFAULT_URL.equals(Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL)))
    +
              */
    +  105  24
             boolean retval = false;
     106   +
             try {
    +  107  24
                 if ((!DEFAULT_URL.equals(Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL)))
    +  108  
                         && Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED)) {
    -  107  0
                     LOGGER.info("Enabling Nexus analyzer");
    -  108  0
                     retval = true;
    -  109   -
                 } else {
    -  110  2
                     LOGGER.fine("Nexus analyzer disabled, using Central instead");
    +  109  0
                     LOGGER.info("Enabling Nexus analyzer");
    +  110  0
                     retval = true;
     111   +
                 } else {
    +  112  24
                     LOGGER.debug("Nexus analyzer disabled, using Central instead");
    +  113  
                 }
    -  112  0
             } catch (InvalidSettingException ise) {
    -  113  0
                 LOGGER.warning("Invalid setting. Disabling Nexus analyzer");
    -  114  2
             }
    -  115   -
     
    -  116  2
             return retval;
    +  114  0
             } catch (InvalidSettingException ise) {
    +  115  0
                 LOGGER.warn("Invalid setting. Disabling Nexus analyzer");
    +  116  24
             }
     117   -
         }
    -  118  
     
    +  118  24
             return retval;
     119   -
         /**
    +
         }
     120   -
          * Determine whether to enable this analyzer or not.
    +
     
     121   -
          *
    +
         /**
     122   -
          * @return whether the analyzer should be enabled
    +
          * Determine whether to enable this analyzer or not.
     123   -
          */
    +
          *
     124   -
         @Override
    +
          * @return whether the analyzer should be enabled
     125   -
         public boolean isEnabled() {
    -  126  0
             return enabled;
    +
          */
    +  126   +
         @Override
     127   -
         }
    -  128   -
     
    +
         public boolean isEnabled() {
    +  128  0
             return enabled;
     129   -
         /**
    +
         }
     130   -
          * Initializes the analyzer once before any analysis is performed.
    +
     
     131   -
          *
    +
         /**
     132   -
          * @throws Exception if there's an error during initialization
    +
          * Initializes the analyzer once before any analysis is performed.
     133   -
          */
    +
          *
     134   -
         @Override
    +
          * @throws Exception if there's an error during initialization
     135   +
          */
    +  136   +
         @Override
    +  137  
         public void initializeFileTypeAnalyzer() throws Exception {
    -  136  0
             LOGGER.fine("Initializing Nexus Analyzer");
    -  137  0
             LOGGER.fine(String.format("Nexus Analyzer enabled: %s", isEnabled()));
    -  138  0
             if (isEnabled()) {
    -  139  0
                 final String searchUrl = Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL);
    -  140  0
                 LOGGER.fine(String.format("Nexus Analyzer URL: %s", searchUrl));
    -  141   +  138  0
             LOGGER.debug("Initializing Nexus Analyzer");
    +  139  0
             LOGGER.debug("Nexus Analyzer enabled: {}", isEnabled());
    +  140  0
             if (isEnabled()) {
    +  141  0
                 final String searchUrl = Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL);
    +  142  0
                 LOGGER.debug("Nexus Analyzer URL: {}", searchUrl);
    +  143  
                 try {
    -  142  0
                     searcher = new NexusSearch(new URL(searchUrl));
    -  143  0
                     if (!searcher.preflightRequest()) {
    -  144  0
                         LOGGER.warning("There was an issue getting Nexus status. Disabling analyzer.");
    -  145  0
                         setEnabled(false);
    -  146   -
                     }
    -  147  0
                 } catch (MalformedURLException mue) {
    +  144  0
                     searcher = new NexusSearch(new URL(searchUrl));
    +  145  0
                     if (!searcher.preflightRequest()) {
    +  146  0
                         LOGGER.warn("There was an issue getting Nexus status. Disabling analyzer.");
    +  147  0
                         setEnabled(false);
     148   +
                     }
    +  149  0
                 } catch (MalformedURLException mue) {
    +  150  
                     // I know that initialize can throw an exception, but we'll
    -  149   +  151  
                     // just disable the analyzer if the URL isn't valid
    -  150  0
                     LOGGER.warning(String.format("Property %s not a valid URL. Nexus Analyzer disabled", searchUrl));
    -  151  0
                     setEnabled(false);
    -  152  0
                 }
    -  153   -
             }
    -  154  0
         }
    +  152  0
                     LOGGER.warn("Property {} not a valid URL. Nexus Analyzer disabled", searchUrl);
    +  153  0
                     setEnabled(false);
    +  154  0
                 }
     155   -
     
    -  156   -
         /**
    +
             }
    +  156  0
         }
     157   -
          * Returns the analyzer's name.
    +
     
     158   -
          *
    +
         /**
     159   -
          * @return the name of the analyzer
    +
          * Returns the analyzer's name.
     160   -
          */
    +
          *
     161   -
         @Override
    +
          * @return the name of the analyzer
     162   -
         public String getName() {
    -  163  4
             return ANALYZER_NAME;
    +
          */
    +  163   +
         @Override
     164   -
         }
    -  165   -
     
    +
         public String getName() {
    +  165  32
             return ANALYZER_NAME;
     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
    +
          * Returns the key used in the properties file to reference the analyzer's enabled property.
     170   -
          */
    +
          *
     171   -
         @Override
    +
          * @return the analyzer's enabled property setting key
     172   -
         protected String getAnalyzerEnabledSettingKey() {
    -  173  2
             return Settings.KEYS.ANALYZER_NEXUS_ENABLED;
    -  174   -
         }
    -  175   -
     
    -  176   -
         /**
    -  177   -
          * Returns the analysis phase under which the analyzer runs.
    -  178   -
          *
    -  179   -
          * @return the phase under which this analyzer runs
    -  180  
          */
    -  181   +  173  
         @Override
    -  182   -
         public AnalysisPhase getAnalysisPhase() {
    -  183  1
             return ANALYSIS_PHASE;
    -  184   +  174   +
         protected String getAnalyzerEnabledSettingKey() {
    +  175  24
             return Settings.KEYS.ANALYZER_NEXUS_ENABLED;
    +  176  
         }
    -  185   +  177  
     
    -  186   +  178  
         /**
    -  187   -
          * Returns the extensions for which this Analyzer runs.
    -  188   +  179   +
          * Returns the analysis phase under which the analyzer runs.
    +  180  
          *
    +  181   +
          * @return the phase under which this analyzer runs
    +  182   +
          */
    +  183   +
         @Override
    +  184   +
         public AnalysisPhase getAnalysisPhase() {
    +  185  16
             return ANALYSIS_PHASE;
    +  186   +
         }
    +  187   +
     
    +  188   +
         /**
     189   -
          * @return the extensions for which this Analyzer runs
    +
          * The file filter used to determine which files this analyzer supports.
     190  
          */
    -  191   -
         @Override
    +  191  8
         private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(SUPPORTED_EXTENSIONS).build();
     192   -
         public Set<String> getSupportedExtensions() {
    -  193  0
             return SUPPORTED_EXTENSIONS;
    -  194   -
         }
    -  195  
     
    -  196   +  193  
         /**
    -  197   -
          * Performs the analysis.
    -  198   +  194   +
          * Returns the FileFilter
    +  195  
          *
    -  199   -
          * @param dependency the dependency to analyze
    -  200   -
          * @param engine the engine
    -  201   -
          * @throws AnalysisException when there's an exception during analysis
    -  202   +  196   +
          * @return the FileFilter
    +  197  
          */
    -  203   +  198  
         @Override
    +  199   +
         protected FileFilter getFileFilter() {
    +  200  6824
             return FILTER;
    +  201   +
         }
    +  202   +
     
    +  203   +
         /**
     204   -
         public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException {
    -  205  0
             if (!isEnabled()) {
    -  206  0
                 return;
    +
          * Performs the analysis.
    +  205   +
          *
    +  206   +
          * @param dependency the dependency to analyze
     207   -
             }
    +
          * @param engine the engine
     208   +
          * @throws AnalysisException when there's an exception during analysis
    +  209   +
          */
    +  210   +
         @Override
    +  211   +
         public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException {
    +  212  0
             if (!isEnabled()) {
    +  213  0
                 return;
    +  214   +
             }
    +  215  
             try {
    -  209  0
                 final MavenArtifact ma = searcher.searchSha1(dependency.getSha1sum());
    -  210  0
                 dependency.addAsEvidence("nexus", ma, Confidence.HIGH);
    -  211  0
                 boolean pomAnalyzed = false;
    -  212  0
                 LOGGER.fine("POM URL " + ma.getPomUrl());
    -  213  0
                 for (Evidence e : dependency.getVendorEvidence()) {
    -  214  0
                     if ("pom".equals(e.getSource())) {
    -  215  0
                         pomAnalyzed = true;
    -  216  0
                         break;
    -  217   +  216  0
                 final MavenArtifact ma = searcher.searchSha1(dependency.getSha1sum());
    +  217  0
                 dependency.addAsEvidence("nexus", ma, Confidence.HIGH);
    +  218  0
                 boolean pomAnalyzed = false;
    +  219  0
                 LOGGER.debug("POM URL {}", ma.getPomUrl());
    +  220  0
                 for (Evidence e : dependency.getVendorEvidence()) {
    +  221  0
                     if ("pom".equals(e.getSource())) {
    +  222  0
                         pomAnalyzed = true;
    +  223  0
                         break;
    +  224  
                     }
    -  218  0
                 }
    -  219  0
                 if (!pomAnalyzed && ma.getPomUrl() != null) {
    -  220  0
                     File pomFile = null;
    -  221   +  225  0
                 }
    +  226  0
                 if (!pomAnalyzed && ma.getPomUrl() != null) {
    +  227  0
                     File pomFile = null;
    +  228  
                     try {
    -  222  0
                         final File baseDir = Settings.getTempDirectory();
    -  223  0
                         pomFile = File.createTempFile("pom", ".xml", baseDir);
    -  224  0
                         if (!pomFile.delete()) {
    -  225  0
                             final String msg = String.format("Unable to fetch pom.xml for %s from Nexus repository; "
    -  226   +  229  0
                         final File baseDir = Settings.getTempDirectory();
    +  230  0
                         pomFile = File.createTempFile("pom", ".xml", baseDir);
    +  231  0
                         if (!pomFile.delete()) {
    +  232  0
                             LOGGER.warn("Unable to fetch pom.xml for {} from Nexus repository; "
    +  233  
                                     + "this could result in undetected CPE/CVEs.", dependency.getFileName());
    -  227  0
                             LOGGER.warning(msg);
    -  228  0
                             LOGGER.fine("Unable to delete temp file");
    -  229   -
                         }
    -  230  0
                         LOGGER.fine(String.format("Downloading %s", ma.getPomUrl()));
    -  231  0
                         Downloader.fetchFile(new URL(ma.getPomUrl()), pomFile);
    -  232  0
                         PomUtils.analyzePOM(dependency, pomFile);
    -  233  0
                     } catch (DownloadFailedException ex) {
    -  234  0
                         final String msg = String.format("Unable to download pom.xml for %s from Nexus repository; "
    +  234  0
                             LOGGER.debug("Unable to delete temp file");
     235   -
                                 + "this could result in undetected CPE/CVEs.", dependency.getFileName());
    -  236  0
                         LOGGER.warning(msg);
    -  237   -
                     } finally {
    -  238  0
                         if (pomFile != null && !FileUtils.deleteQuietly(pomFile)) {
    -  239  0
                             pomFile.deleteOnExit();
    -  240  
                         }
    +  236  0
                         LOGGER.debug("Downloading {}", ma.getPomUrl());
    +  237  0
                         Downloader.fetchFile(new URL(ma.getPomUrl()), pomFile);
    +  238  0
                         PomUtils.analyzePOM(dependency, pomFile);
    +  239  0
                     } catch (DownloadFailedException ex) {
    +  240  0
                         LOGGER.warn("Unable to download pom.xml for {} from Nexus repository; "
     241   -
                     }
    +
                                 + "this could result in undetected CPE/CVEs.", dependency.getFileName());
     242   -
                 }
    -  243  0
             } catch (IllegalArgumentException iae) {
    -  244   -
                 //dependency.addAnalysisException(new AnalysisException("Invalid SHA-1"));
    -  245  0
                 LOGGER.info(String.format("invalid sha-1 hash on %s", dependency.getFileName()));
    -  246  0
             } catch (FileNotFoundException fnfe) {
    +
                     } finally {
    +  243  0
                         if (pomFile != null && !FileUtils.deleteQuietly(pomFile)) {
    +  244  0
                             pomFile.deleteOnExit();
    +  245   +
                         }
    +  246   +
                     }
     247   +
                 }
    +  248  0
             } catch (IllegalArgumentException iae) {
    +  249   +
                 //dependency.addAnalysisException(new AnalysisException("Invalid SHA-1"));
    +  250  0
                 LOGGER.info(String.format("invalid sha-1 hash on %s", dependency.getFileName()));
    +  251  0
             } catch (FileNotFoundException fnfe) {
    +  252  
                 //dependency.addAnalysisException(new AnalysisException("Artifact not found on repository"));
    -  248  0
                 LOGGER.fine(String.format("Artifact not found in repository '%s'", dependency.getFileName()));
    -  249  0
                 LOGGER.log(Level.FINE, fnfe.getMessage(), fnfe);
    -  250  0
             } catch (IOException ioe) {
    -  251   +  253  0
                 LOGGER.debug("Artifact not found in repository '{}'", dependency.getFileName());
    +  254  0
                 LOGGER.debug(fnfe.getMessage(), fnfe);
    +  255  0
             } catch (IOException ioe) {
    +  256  
                 //dependency.addAnalysisException(new AnalysisException("Could not connect to repository", ioe));
    -  252  0
                 LOGGER.log(Level.FINE, "Could not connect to nexus repository", ioe);
    -  253  0
             }
    -  254  0
         }
    -  255   +  257  0
                 LOGGER.debug("Could not connect to nexus repository", ioe);
    +  258  0
             }
    +  259  0
         }
    +  260  
     }
    - + 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 b2f4f5efe..bc3fba3c6 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.NuspecAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.NuspecAnalyzer.html @@ -56,246 +56,262 @@  19  
     
     20   -
     import java.io.FileInputStream;
    -  21   -
     import java.io.FileNotFoundException;
    -  22   -
     import java.io.IOException;
    -  23   -
     import java.util.Set;
    -  24   -
     import java.util.logging.Level;
    -  25   -
     import java.util.logging.Logger;
    -  26  
     import org.owasp.dependencycheck.Engine;
    -  27   +  21  
     import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
    -  28   +  22  
     import org.owasp.dependencycheck.data.nuget.NugetPackage;
    -  29   +  23  
     import org.owasp.dependencycheck.data.nuget.NuspecParseException;
    -  30   +  24  
     import org.owasp.dependencycheck.data.nuget.NuspecParser;
    -  31   +  25  
     import org.owasp.dependencycheck.data.nuget.XPathNuspecParser;
    -  32   +  26  
     import org.owasp.dependencycheck.dependency.Confidence;
    -  33   +  27  
     import org.owasp.dependencycheck.dependency.Dependency;
    -  34   +  28   +
     import org.owasp.dependencycheck.utils.FileFilterBuilder;
    +  29  
     import org.owasp.dependencycheck.utils.Settings;
    +  30   +
     import org.slf4j.Logger;
    +  31   +
     import org.slf4j.LoggerFactory;
    +  32   +
     
    +  33   +
     import java.io.FileFilter;
    +  34   +
     import java.io.FileInputStream;
     35   -
     
    +
     import java.io.FileNotFoundException;
     36   -
     /**
    +
     import java.io.IOException;
     37   -
      * Analyzer which will parse a Nuspec file to gather module information.
    +
     
     38   -
      *
    +
     /**
     39   -
      * @author colezlaw
    +
      * Analyzer which will parse a Nuspec file to gather module information.
     40   -
      */
    -  41  6
     public class NuspecAnalyzer extends AbstractFileTypeAnalyzer {
    +
      *
    +  41   +
      * @author colezlaw
     42   -
     
    -  43   -
         /**
    +
      */
    +  43  48
     public class NuspecAnalyzer extends AbstractFileTypeAnalyzer {
     44   -
          * The logger.
    +
     
     45   -
          */
    -  46  1
         private static final Logger LOGGER = Logger.getLogger(NuspecAnalyzer.class.getName());
    +
         /**
    +  46   +
          * The logger.
     47   -
     
    -  48   -
         /**
    +
          */
    +  48  8
         private static final Logger LOGGER = LoggerFactory.getLogger(NuspecAnalyzer.class);
     49   -
          * The name of the analyzer.
    +
     
     50   -
          */
    +
         /**
     51   -
         private static final String ANALYZER_NAME = "Nuspec Analyzer";
    +
          * The name of the analyzer.
     52   -
     
    +
          */
     53   -
         /**
    +
         private static final String ANALYZER_NAME = "Nuspec Analyzer";
     54   -
          * The phase in which the analyzer runs.
    +
     
     55   -
          */
    -  56  1
         private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
    +
         /**
    +  56   +
          * The phase in which the analyzer runs.
     57   -
     
    -  58   -
         /**
    +
          */
    +  58  8
         private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
     59   -
          * The types of files on which this will work.
    +
     
     60   -
          */
    -  61  1
         private static final Set<String> SUPPORTED_EXTENSIONS = newHashSet("nuspec");
    +
         /**
    +  61   +
          * The types of files on which this will work.
     62   -
     
    +
          */
     63   -
         /**
    +
         private static final String SUPPORTED_EXTENSIONS = "nuspec";
     64   -
          * Initializes the analyzer once before any analysis is performed.
    +
     
     65   -
          *
    +
         /**
     66   -
          * @throws Exception if there's an error during initialization
    +
          * Initializes the analyzer once before any analysis is performed.
     67   -
          */
    +
          *
     68   -
         @Override
    +
          * @throws Exception if there's an error during initialization
     69   -
         public void initializeFileTypeAnalyzer() throws Exception {
    -  70  0
         }
    +
          */
    +  70   +
         @Override
     71   -
     
    -  72   -
         /**
    +
         public void initializeFileTypeAnalyzer() throws Exception {
    +  72  0
         }
     73   -
          * Returns the analyzer's name.
    +
     
     74   -
          *
    +
         /**
     75   -
          * @return the name of the analyzer
    +
          * Returns the analyzer's name.
     76   -
          */
    +
          *
     77   -
         @Override
    +
          * @return the name of the analyzer
     78   -
         public String getName() {
    -  79  5
             return ANALYZER_NAME;
    +
          */
    +  79   +
         @Override
     80   -
         }
    -  81   -
     
    +
         public String getName() {
    +  81  40
             return ANALYZER_NAME;
     82   -
         /**
    +
         }
     83   -
          * Returns the key used in the properties file to reference the analyzer's enabled property.
    +
     
     84   -
          *
    +
         /**
     85   -
          * @return the analyzer's enabled property setting key
    +
          * Returns the key used in the properties file to reference the analyzer's enabled property.
     86   -
          */
    +
          *
     87   -
         @Override
    +
          * @return the analyzer's enabled property setting key
     88   -
         protected String getAnalyzerEnabledSettingKey() {
    -  89  6
             return Settings.KEYS.ANALYZER_NUSPEC_ENABLED;
    -  90   -
         }
    -  91   -
     
    -  92   -
         /**
    -  93   -
          * Returns the analysis phase under which the analyzer runs.
    -  94   -
          *
    -  95   -
          * @return the phase under which this analyzer runs
    -  96  
          */
    -  97   +  89  
         @Override
    -  98   -
         public AnalysisPhase getAnalysisPhase() {
    -  99  2
             return ANALYSIS_PHASE;
    -  100   +  90   +
         protected String getAnalyzerEnabledSettingKey() {
    +  91  48
             return Settings.KEYS.ANALYZER_NUSPEC_ENABLED;
    +  92  
         }
    -  101   +  93  
     
    -  102   +  94  
         /**
    -  103   -
          * Returns the extensions for which this Analyzer runs.
    -  104   +  95   +
          * Returns the analysis phase under which the analyzer runs.
    +  96  
          *
    +  97   +
          * @return the phase under which this analyzer runs
    +  98   +
          */
    +  99   +
         @Override
    +  100   +
         public AnalysisPhase getAnalysisPhase() {
    +  101  24
             return ANALYSIS_PHASE;
    +  102   +
         }
    +  103   +
     
    +  104   +
         /**
     105   -
          * @return the extensions for which this Analyzer runs
    +
          * The file filter used to determine which files this analyzer supports.
     106  
          */
    -  107   -
         @Override
    +  107  8
         private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(
     108   -
         public Set<String> getSupportedExtensions() {
    -  109  852
             return SUPPORTED_EXTENSIONS;
    +
                 SUPPORTED_EXTENSIONS).build();
    +  109   +
     
     110   -
         }
    -  111   -
     
    -  112  
         /**
    -  113   -
          * Performs the analysis.
    -  114   +  111   +
          * Returns the FileFilter
    +  112  
          *
    -  115   -
          * @param dependency the dependency to analyze
    -  116   -
          * @param engine the engine
    -  117   -
          * @throws AnalysisException when there's an exception during analysis
    -  118   +  113   +
          * @return the FileFilter
    +  114  
          */
    -  119   +  115  
         @Override
    -  120   -
         public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException {
    -  121  0
             LOGGER.log(Level.FINE, "Checking Nuspec file {0}", dependency.toString());
    -  122   -
             try {
    -  123  0
                 final NuspecParser parser = new XPathNuspecParser();
    -  124  0
                 NugetPackage np = null;
    -  125  0
                 FileInputStream fis = null;
    -  126   -
                 try {
    -  127  0
                     fis = new FileInputStream(dependency.getActualFilePath());
    -  128  0
                     np = parser.parse(fis);
    -  129  0
                 } catch (NuspecParseException ex) {
    -  130  0
                     throw new AnalysisException(ex);
    -  131  0
                 } catch (FileNotFoundException ex) {
    -  132  0
                     throw new AnalysisException(ex);
    -  133   -
                 } finally {
    -  134  0
                     if (fis != null) {
    -  135   -
                         try {
    -  136  0
                             fis.close();
    -  137  0
                         } catch (IOException e) {
    -  138  0
                             LOGGER.fine("Error closing input stream");
    -  139  0
                         }
    -  140   -
                     }
    -  141   -
                 }
    -  142   +  116   +
         protected FileFilter getFileFilter() {
    +  117  6840
             return FILTER;
    +  118   +
         }
    +  119  
     
    -  143  0
                 if (np.getOwners() != null) {
    -  144  0
                     dependency.getVendorEvidence().addEvidence("nuspec", "owners", np.getOwners(), Confidence.HIGHEST);
    -  145   +  120   +
         /**
    +  121   +
          * Performs the analysis.
    +  122   +
          *
    +  123   +
          * @param dependency the dependency to analyze
    +  124   +
          * @param engine the engine
    +  125   +
          * @throws AnalysisException when there's an exception during analysis
    +  126   +
          */
    +  127   +
         @Override
    +  128   +
         public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException {
    +  129  0
             LOGGER.debug("Checking Nuspec file {}", dependency.toString());
    +  130   +
             try {
    +  131  0
                 final NuspecParser parser = new XPathNuspecParser();
    +  132  0
                 NugetPackage np = null;
    +  133  0
                 FileInputStream fis = null;
    +  134   +
                 try {
    +  135  0
                     fis = new FileInputStream(dependency.getActualFilePath());
    +  136  0
                     np = parser.parse(fis);
    +  137  0
                 } catch (NuspecParseException ex) {
    +  138  0
                     throw new AnalysisException(ex);
    +  139  0
                 } catch (FileNotFoundException ex) {
    +  140  0
                     throw new AnalysisException(ex);
    +  141   +
                 } finally {
    +  142  0
                     if (fis != null) {
    +  143   +
                         try {
    +  144  0
                             fis.close();
    +  145  0
                         } catch (IOException e) {
    +  146  0
                             LOGGER.debug("Error closing input stream");
    +  147  0
                         }
    +  148   +
                     }
    +  149  
                 }
    -  146  0
                 dependency.getVendorEvidence().addEvidence("nuspec", "authors", np.getAuthors(), Confidence.HIGH);
    -  147  0
                 dependency.getVersionEvidence().addEvidence("nuspec", "version", np.getVersion(), Confidence.HIGHEST);
    -  148  0
                 dependency.getProductEvidence().addEvidence("nuspec", "id", np.getId(), Confidence.HIGHEST);
    -  149  0
                 if (np.getTitle() != null) {
    -  150  0
                     dependency.getProductEvidence().addEvidence("nuspec", "title", np.getTitle(), Confidence.MEDIUM);
    -  151   +  150   +
     
    +  151  0
                 if (np.getOwners() != null) {
    +  152  0
                     dependency.getVendorEvidence().addEvidence("nuspec", "owners", np.getOwners(), Confidence.HIGHEST);
    +  153  
                 }
    -  152  0
             } catch (Throwable e) {
    -  153  0
                 throw new AnalysisException(e);
    -  154  0
             }
    -  155  0
         }
    -  156   +  154  0
                 dependency.getVendorEvidence().addEvidence("nuspec", "authors", np.getAuthors(), Confidence.HIGH);
    +  155  0
                 dependency.getVersionEvidence().addEvidence("nuspec", "version", np.getVersion(), Confidence.HIGHEST);
    +  156  0
                 dependency.getProductEvidence().addEvidence("nuspec", "id", np.getId(), Confidence.HIGHEST);
    +  157  0
                 if (np.getTitle() != null) {
    +  158  0
                     dependency.getProductEvidence().addEvidence("nuspec", "title", np.getTitle(), Confidence.MEDIUM);
    +  159   +
                 }
    +  160  0
             } catch (Throwable e) {
    +  161  0
                 throw new AnalysisException(e);
    +  162  0
             }
    +  163  0
         }
    +  164  
     }
    - + 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 251964b8c..e1d61120f 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  2
     public class NvdCveAnalyzer implements Analyzer {
    +  37  24
     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  8
             cveDB = new CveDB();
    +  58  8
             cveDB.open();
    +  59  8
         }
     60  
     
     61   @@ -143,9 +143,9 @@
         @Override
     65  
         public void close() {
    -  66  1
             cveDB.close();
    -  67  1
             cveDB = null;
    -  68  1
         }
    +  66  8
             cveDB.close();
    +  67  8
             cveDB = null;
    +  68  8
         }
     69  
     
     70   @@ -160,7 +160,7 @@
          */
     75  
         public boolean isOpen() {
    -  76  1
             return (cveDB != null);
    +  76  17
             return (cveDB != null);
     77  
         }
     78   @@ -179,12 +179,12 @@
         @Override
     85  
         protected void finalize() throws Throwable {
    -  86  1
             super.finalize();
    -  87  1
             if (isOpen()) {
    +  86  17
             super.finalize();
    +  87  17
             if (isOpen()) {
     88  0
                 close();
     89  
             }
    -  90  1
         }
    +  90  17
         }
     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  2
                 if ("cpe".equals(id.getType())) {
    +  101  16
             for (Identifier id : dependency.getIdentifiers()) {
    +  102  24
                 if ("cpe".equals(id.getType())) {
     103  
                     try {
    -  104  2
                         final String value = id.getValue();
    -  105  2
                         final List<Vulnerability> vulns = cveDB.getVulnerabilities(value);
    -  106  2
                         dependency.getVulnerabilities().addAll(vulns);
    +  104  24
                         final String value = id.getValue();
    +  105  24
                         final List<Vulnerability> vulns = cveDB.getVulnerabilities(value);
    +  106  24
                         dependency.getVulnerabilities().addAll(vulns);
     107  0
                     } catch (DatabaseException ex) {
     108  0
                         throw new AnalysisException(ex);
    -  109  2
                     }
    +  109  24
                     }
     110  
                 }
    -  111  2
             }
    -  112  2
             for (Identifier id : dependency.getSuppressedIdentifiers()) {
    +  111  24
             }
    +  112  16
             for (Identifier id : dependency.getSuppressedIdentifiers()) {
     113  0
                 if ("cpe".equals(id.getType())) {
     114  
                     try {
    @@ -231,7 +231,7 @@  121  
                 }
     122  0
             }
    -  123  2
         }
    +  123  16
         }
     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  1
             return AnalysisPhase.FINDING_ANALYSIS;
    +  142  16
             return AnalysisPhase.FINDING_ANALYSIS;
     143  
         }
     144   @@ -286,12 +286,12 @@
         @Override
     151  
         public void initialize() throws Exception {
    -  152  1
             this.open();
    -  153  1
         }
    +  152  8
             this.open();
    +  153  8
         }
     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 new file mode 100644 index 000000000..dc430ab3e --- /dev/null +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.OpenSSLAnalyzer.html @@ -0,0 +1,338 @@ + + + + +Coverage Report + + + + +
    Coverage Report - org.owasp.dependencycheck.analyzer.OpenSSLAnalyzer
    +
     
    + + + + +
    Classes in this File Line Coverage Branch Coverage Complexity
    OpenSSLAnalyzer
    91%
    33/36
    71%
    10/14
    2.125
    +
     
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
     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) 2015 Institute for Defense Analyses. All Rights Reserved.
     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.utils.FileFilterBuilder;
     26  
     import org.owasp.dependencycheck.utils.Settings;
     27  
     
     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 <dvisser@ida.org>
     38  
      */
     39  56
     public class OpenSSLAnalyzer extends AbstractFileTypeAnalyzer {
     40  
     
     41  
         private static final int HEXADECIMAL = 16;
     42  
         /**
     43  
          * Filename to analyze. All other .h files get removed from consideration.
     44  
          */
     45  
         private static final String OPENSSLV_H = "opensslv.h";
     46  
     
     47  
         /**
     48  
          * Filter that detects files named "__init__.py".
     49  
          */
     50  8
         private static final FileFilter OPENSSLV_FILTER = FileFilterBuilder.newInstance().addFilenames(OPENSSLV_H).build();
     51  8
         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  72
             final long major = openSSLVersionConstant >>> MAJOR_OFFSET;
     72  72
             final long minor = (openSSLVersionConstant & MINOR_MASK) >>> MINOR_OFFSET;
     73  72
             final long fix = (openSSLVersionConstant & FIX_MASK) >>> FIX_OFFSET;
     74  72
             final long patchLevel = (openSSLVersionConstant & PATCH_MASK) >>> PATCH_OFFSET;
     75  72
             final String patch = 0 == patchLevel || patchLevel > NUM_LETTERS ? "" : String.valueOf((char) (patchLevel + 'a' - 1));
     76  72
             final int statusCode = (int) (openSSLVersionConstant & STATUS_MASK);
     77  72
             final String status = 0xf == statusCode ? "" : (0 == statusCode ? "-dev" : "-beta" + statusCode);
     78  72
             return String.format("%d.%d.%d%s%s", major, minor, fix, patch, status);
     79  
         }
     80  
     
     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  40
             return "OpenSSL Source Analyzer";
     89  
         }
     90  
     
     91  
         /**
     92  
          * Tell that we are used for information collection.
     93  
          *
     94  
          * @return INFORMATION_COLLECTION
     95  
          */
     96  
         @Override
     97  
         public AnalysisPhase getAnalysisPhase() {
     98  16
             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  6832
             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  32
         }
     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  8
             final File file = dependency.getActualFile();
     132  8
             final String parentName = file.getParentFile().getName();
     133  8
             boolean found = false;
     134  8
             final String contents = getFileContents(file);
     135  8
             if (!contents.isEmpty()) {
     136  8
                 final Matcher matcher = VERSION_PATTERN.matcher(contents);
     137  8
                 if (matcher.find()) {
     138  8
                     dependency.getVersionEvidence().addEvidence(OPENSSLV_H, "Version Constant",
     139  
                             getOpenSSLVersion(Long.parseLong(matcher.group(1), HEXADECIMAL)), Confidence.HIGH);
     140  8
                     found = true;
     141  
                 }
     142  
             }
     143  8
             if (found) {
     144  8
                 dependency.setDisplayFileName(parentName + File.separatorChar + OPENSSLV_H);
     145  8
                 dependency.getVendorEvidence().addEvidence(OPENSSLV_H, "Vendor", "OpenSSL", Confidence.HIGHEST);
     146  8
                 dependency.getProductEvidence().addEvidence(OPENSSLV_H, "Product", "OpenSSL", Confidence.HIGHEST);
     147  
             } else {
     148  0
                 engine.getDependencies().remove(dependency);
     149  
             }
     150  8
         }
     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  8
                 contents = FileUtils.readFileToString(actualFile).trim();
     164  0
             } catch (IOException e) {
     165  0
                 throw new AnalysisException(
     166  
                         "Problem occurred while reading dependency file.", e);
     167  8
             }
     168  8
             return contents;
     169  
         }
     170  
     
     171  
         @Override
     172  
         protected String getAnalyzerEnabledSettingKey() {
     173  56
             return Settings.KEYS.ANALYZER_OPENSSL_ENABLED;
     174  
         }
     175  
     }
    + + + + 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 cd62858bd..1c374395c 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.PythonDistributionAnalyzer.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.analyzer.PythonDistributionAnalyzer.html @@ -12,7 +12,7 @@
     
    - +
    Classes in this File Line Coverage Branch Coverage Complexity
    PythonDistributionAnalyzer
    86%
    78/90
    65%
    30/46
    3.308
    PythonDistributionAnalyzer
    86%
    80/92
    65%
    30/46
    3.308
     
    @@ -60,254 +60,253 @@  21  
     import java.io.File;
     22   -
     import java.io.FileInputStream;
    +
     import java.io.FileFilter;
     23   -
     import java.io.FileNotFoundException;
    +
     import java.io.FileInputStream;
     24   -
     import java.io.FilenameFilter;
    +
     import java.io.FileNotFoundException;
     25   -
     import java.util.Set;
    +
     import java.io.FilenameFilter;
     26   -
     import java.util.logging.Level;
    -  27   -
     import java.util.logging.Logger;
    -  28   -
     import java.util.regex.Pattern;
    -  29   -
     
    -  30   -
     import javax.mail.MessagingException;
    -  31   -
     import javax.mail.internet.InternetHeaders;
    -  32   -
     
    -  33  
     import org.apache.commons.io.filefilter.NameFileFilter;
    -  34   +  27  
     import org.apache.commons.io.filefilter.SuffixFileFilter;
    -  35   +  28  
     import org.apache.commons.io.input.AutoCloseInputStream;
    -  36   +  29  
     import org.apache.commons.lang.StringUtils;
    -  37   +  30  
     import org.owasp.dependencycheck.Engine;
    -  38   +  31  
     import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
    -  39   +  32  
     import org.owasp.dependencycheck.dependency.Confidence;
    -  40   +  33  
     import org.owasp.dependencycheck.dependency.Dependency;
    -  41   +  34  
     import org.owasp.dependencycheck.dependency.EvidenceCollection;
    -  42   +  35   +
     import org.slf4j.Logger;
    +  36   +
     import org.slf4j.LoggerFactory;
    +  37   +
     
    +  38   +
     import javax.mail.MessagingException;
    +  39   +
     import javax.mail.internet.InternetHeaders;
    +  40  
     import org.owasp.dependencycheck.utils.ExtractionException;
    -  43   +  41  
     import org.owasp.dependencycheck.utils.ExtractionUtil;
    -  44   +  42   +
     import org.owasp.dependencycheck.utils.FileFilterBuilder;
    +  43  
     import org.owasp.dependencycheck.utils.FileUtils;
    -  45   +  44  
     import org.owasp.dependencycheck.utils.Settings;
    -  46   +  45  
     import org.owasp.dependencycheck.utils.UrlStringUtils;
    +  46   +
     
     47   -
     
    -  48  
     /**
    -  49   +  48  
      * Used to analyze a Wheel or egg distribution files, or their contents in unzipped form, and collect information that can be used
    -  50   +  49  
      * to determine the associated CPE.
    -  51   +  50  
      *
    -  52   +  51  
      * @author Dale Visser <dvisser@ida.org>
    -  53   +  52  
      */
    -  54  11
     public class PythonDistributionAnalyzer extends AbstractFileTypeAnalyzer {
    +  53  88
     public class PythonDistributionAnalyzer extends AbstractFileTypeAnalyzer {
    +  54   +
     
     55   -
     
    +
         /**
     56   -
         /**
    -  57  
          * Name of egg metatdata files to analyze.
    +  57   +
          */
     58   -
          */
    -  59  
         private static final String PKG_INFO = "PKG-INFO";
    +  59   +
     
     60   -
     
    +
         /**
     61   -
         /**
    -  62  
          * Name of wheel metadata files to analyze.
    +  62   +
          */
     63   -
          */
    -  64  
         private static final String METADATA = "METADATA";
    +  64   +
     
     65   -
     
    +
         /**
     66   -
         /**
    -  67  
          * The logger.
    -  68   +  67  
          */
    -  69  1
         private static final Logger LOGGER = Logger
    +  68  8
         private static final Logger LOGGER = LoggerFactory
    +  69   +
                 .getLogger(PythonDistributionAnalyzer.class);
     70   -
                 .getLogger(PythonDistributionAnalyzer.class.getName());
    +
     
     71   -
     
    +
         /**
     72   -
         /**
    -  73  
          * The count of directories created during analysis. This is used for creating temporary directories.
    -  74   +  73  
          */
    -  75  1
         private static int dirCount = 0;
    +  74  8
         private static int dirCount = 0;
    +  75   +
     
     76   -
     
    +
         /**
     77   -
         /**
    -  78  
          * The name of the analyzer.
    +  78   +
          */
     79   -
          */
    -  80  
         private static final String ANALYZER_NAME = "Python Distribution Analyzer";
    +  80   +
         /**
     81   -
         /**
    -  82  
          * The phase that this analyzer is intended to run in.
    -  83   +  82  
          */
    -  84  1
         private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
    +  83  8
         private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
    +  84   +
     
     85   -
     
    +
         /**
     86   -
         /**
    -  87  
          * The set of file extensions supported by this analyzer.
    -  88   +  87  
          */
    -  89  1
         private static final Set<String> EXTENSIONS = newHashSet("whl", "egg",
    +  88  8
         private static final String[] EXTENSIONS = {"whl", "egg", "zip"};
    +  89   +
     
     90   -
                 "zip", METADATA, PKG_INFO);
    +
         /**
     91   -
     
    +
          * Used to match on egg archive candidate extensions.
     92   -
         /**
    -  93   -
          * Used to match on egg archive candidate extenssions.
    +
          */
    +  93  8
         private static final FileFilter EGG_OR_ZIP = FileFilterBuilder.newInstance().addExtensions("egg", "zip").build();
     94   -
          */
    -  95  1
         private static final Pattern EGG_OR_ZIP = Pattern.compile("egg|zip");
    +
     
    +  95   +
         /**
     96   -
     
    +
          * Used to detect files with a .whl extension.
     97   -
         /**
    -  98   -
          * The parent directory for the individual directories per archive.
    +
          */
    +  98  8
         private static final FileFilter WHL_FILTER = FileFilterBuilder.newInstance().addExtensions("whl").build();
     99   -
          */
    +
     
     100   -
         private File tempFileLocation;
    +
         /**
     101   -
     
    +
          * The parent directory for the individual directories per archive.
     102   -
         /**
    +
          */
     103   -
          * Filter that detects *.dist-info files (but doesn't verify they are directories.
    +
         private File tempFileLocation;
     104   -
          */
    -  105  1
         private static final FilenameFilter DIST_INFO_FILTER = new SuffixFileFilter(
    +
     
    +  105   +
         /**
     106   -
                 ".dist-info");
    +
          * Filter that detects *.dist-info files (but doesn't verify they are directories.
     107   -
     
    -  108   -
         /**
    +
          */
    +  108  8
         private static final FilenameFilter DIST_INFO_FILTER = new SuffixFileFilter(
     109   -
          * Filter that detects files named "METADATA".
    +
                 ".dist-info");
     110   -
          */
    -  111  1
         private static final FilenameFilter EGG_INFO_FILTER = new NameFileFilter(
    +
     
    +  111   +
         /**
     112   -
                 "EGG-INFO");
    -  113   -
     
    -  114   -
         /**
    -  115  
          * Filter that detects files named "METADATA".
    +  113   +
          */
    +  114  8
         private static final FilenameFilter EGG_INFO_FILTER = new NameFileFilter(
    +  115   +
                 "EGG-INFO");
     116   -
          */
    -  117  1
         private static final FilenameFilter METADATA_FILTER = new NameFileFilter(
    +
     
    +  117   +
         /**
     118   -
                 METADATA);
    +
          * Filter that detects files named "METADATA".
     119   -
     
    -  120   -
         /**
    +
          */
    +  120  8
         private static final NameFileFilter METADATA_FILTER = new NameFileFilter(
     121   -
          * Filter that detects files named "PKG-INFO".
    +
                 METADATA);
     122   -
          */
    -  123  1
         private static final FilenameFilter PKG_INFO_FILTER = new NameFileFilter(
    +
     
    +  123   +
         /**
     124   -
                 PKG_INFO);
    +
          * Filter that detects files named "PKG-INFO".
     125   -
     
    -  126   -
         /**
    +
          */
    +  126  8
         private static final NameFileFilter PKG_INFO_FILTER = new NameFileFilter(
     127   -
          * Returns a list of file EXTENSIONS supported by this analyzer.
    +
                 PKG_INFO);
     128   -
          *
    +
     
     129   -
          * @return a list of file EXTENSIONS supported by this analyzer.
    +
         /**
     130   -
          */
    +
          * The file filter used to determine which files this analyzer supports.
     131   -
         @Override
    -  132   -
         public Set<String> getSupportedExtensions() {
    -  133  854
             return EXTENSIONS;
    +
          */
    +  132  8
         private static final FileFilter FILTER = FileFilterBuilder.newInstance().addFileFilters(
    +  133   +
                 METADATA_FILTER, PKG_INFO_FILTER).addExtensions(EXTENSIONS).build();
     134   -
         }
    +
     
     135   -
     
    +
         /**
     136   -
         /**
    +
          * Returns the FileFilter
     137   -
          * Returns the name of the analyzer.
    +
          *
     138   -
          *
    +
          * @return the FileFilter
     139   -
          * @return the name of the analyzer.
    +
          */
     140   -
          */
    -  141  
         @Override
    -  142   -
         public String getName() {
    -  143  5
             return ANALYZER_NAME;
    -  144   +  141   +
         protected FileFilter getFileFilter() {
    +  142  6864
             return FILTER;
    +  143  
         }
    -  145   +  144  
     
    -  146   +  145  
         /**
    +  146   +
          * Returns the name of the analyzer.
     147   -
          * Returns the phase that the analyzer is intended to run in.
    -  148  
          *
    +  148   +
          * @return the name of the analyzer.
     149   -
          * @return the phase that the analyzer is intended to run in.
    -  150  
          */
    +  150   +
         @Override
     151   -
         public AnalysisPhase getAnalysisPhase() {
    -  152  1
             return ANALYSIS_PHASE;
    +
         public String getName() {
    +  152  40
             return ANALYZER_NAME;
     153  
         }
     154   @@ -315,356 +314,371 @@  155  
         /**
     156   -
          * Returns the key used in the properties file to reference the analyzer's enabled property.
    +
          * Returns the phase that the analyzer is intended to run in.
     157  
          *
     158   -
          * @return the analyzer's enabled property setting key
    +
          * @return the phase that the analyzer is intended to run in.
     159  
          */
     160  
         @Override
     161   -
         protected String getAnalyzerEnabledSettingKey() {
    -  162  11
             return Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED;
    +
         public AnalysisPhase getAnalysisPhase() {
    +  162  16
             return ANALYSIS_PHASE;
     163  
         }
     164  
     
     165   -
         @Override
    +
         /**
     166   -
         protected void analyzeFileType(Dependency dependency, Engine engine)
    +
          * Returns the key used in the properties file to reference the analyzer's enabled property.
     167   -
                 throws AnalysisException {
    -  168  6
             if ("whl".equals(dependency.getFileExtension())) {
    -  169  1
                 collectMetadataFromArchiveFormat(dependency, DIST_INFO_FILTER,
    +
          *
    +  168   +
          * @return the analyzer's enabled property setting key
    +  169   +
          */
     170   -
                         METADATA_FILTER);
    -  171  5
             } else if (EGG_OR_ZIP.matcher(
    -  172   -
                     StringUtils.stripToEmpty(dependency.getFileExtension()))
    +
         @Override
    +  171   +
         protected String getAnalyzerEnabledSettingKey() {
    +  172  88
             return Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED;
     173   -
                     .matches()) {
    -  174  2
                 collectMetadataFromArchiveFormat(dependency, EGG_INFO_FILTER,
    +
         }
    +  174   +
     
     175   -
                         PKG_INFO_FILTER);
    +
         @Override
     176   -
             } else {
    -  177  3
                 final File actualFile = dependency.getActualFile();
    -  178  3
                 final String name = actualFile.getName();
    -  179  3
                 final boolean metadata = METADATA.equals(name);
    -  180  3
                 if (metadata || PKG_INFO.equals(name)) {
    -  181  3
                     final File parent = actualFile.getParentFile();
    -  182  3
                     final String parentName = parent.getName();
    -  183  3
                     dependency.setDisplayFileName(parentName + "/" + name);
    -  184  3
                     if (parent.isDirectory()
    +
         protected void analyzeFileType(Dependency dependency, Engine engine)
    +  177   +
                 throws AnalysisException {
    +  178  48
             final File actualFile = dependency.getActualFile();
    +  179  48
             if (WHL_FILTER.accept(actualFile)) {
    +  180  8
                 collectMetadataFromArchiveFormat(dependency, DIST_INFO_FILTER,
    +  181   +
                         METADATA_FILTER);
    +  182  40
             } else if (EGG_OR_ZIP.accept(actualFile)) {
    +  183  16
                 collectMetadataFromArchiveFormat(dependency, EGG_INFO_FILTER,
    +  184   +
                         PKG_INFO_FILTER);
     185   -
                             && (metadata && parentName.endsWith(".dist-info")
    -  186   -
                             || parentName.endsWith(".egg-info") || "EGG-INFO"
    -  187   -
                             .equals(parentName))) {
    -  188  3
                         collectWheelMetadata(dependency, actualFile);
    -  189   -
                     }
    -  190   -
                 }
    -  191   -
             }
    -  192  6
         }
    -  193   -
     
    -  194   -
         /**
    -  195   -
          * Collects the meta data from an archive.
    -  196   -
          *
    -  197   -
          * @param dependency the archive being scanned
    -  198   -
          * @param folderFilter the filter to apply to the folder
    -  199   -
          * @param metadataFilter the filter to apply to the meta data
    -  200   -
          * @throws AnalysisException thrown when there is a problem analyzing the dependency
    -  201   -
          */
    -  202   -
         private void collectMetadataFromArchiveFormat(Dependency dependency,
    -  203   -
                 FilenameFilter folderFilter, FilenameFilter metadataFilter)
    -  204   -
                 throws AnalysisException {
    -  205  3
             final File temp = getNextTempDirectory();
    -  206  3
             LOGGER.fine(String.format("%s exists? %b", temp, temp.exists()));
    -  207   -
             try {
    -  208  3
                 ExtractionUtil.extractFilesUsingFilter(
    -  209   -
                         new File(dependency.getActualFilePath()), temp,
    -  210   -
                         metadataFilter);
    -  211  0
             } catch (ExtractionException ex) {
    -  212  0
                 throw new AnalysisException(ex);
    -  213  3
             }
    -  214   -
     
    -  215  3
             collectWheelMetadata(
    -  216   -
                     dependency,
    -  217   -
                     getMatchingFile(getMatchingFile(temp, folderFilter),
    -  218   -
                             metadataFilter));
    -  219  3
         }
    -  220   -
     
    -  221   -
         /**
    -  222   -
          * Makes sure a usable temporary directory is available.
    -  223   -
          *
    -  224   -
          * @throws Exception an AnalyzeException is thrown when the temp directory cannot be created
    -  225   -
          */
    -  226   -
         @Override
    -  227   -
         protected void initializeFileTypeAnalyzer() throws Exception {
    -  228  9
             final File baseDir = Settings.getTempDirectory();
    -  229  9
             tempFileLocation = File.createTempFile("check", "tmp", baseDir);
    -  230  9
             if (!tempFileLocation.delete()) {
    -  231  0
                 final String msg = String.format(
    -  232   -
                         "Unable to delete temporary file '%s'.",
    -  233   -
                         tempFileLocation.getAbsolutePath());
    -  234  0
                 throw new AnalysisException(msg);
    -  235   -
             }
    -  236  9
             if (!tempFileLocation.mkdirs()) {
    -  237  0
                 final String msg = String.format(
    -  238   -
                         "Unable to create directory '%s'.",
    -  239   -
                         tempFileLocation.getAbsolutePath());
    -  240  0
                 throw new AnalysisException(msg);
    -  241   -
             }
    -  242  9
         }
    -  243   -
     
    -  244   -
         /**
    -  245   -
          * Deletes any files extracted from the Wheel during analysis.
    -  246   -
          */
    -  247   -
         @Override
    -  248   -
         public void close() {
    -  249  10
             if (tempFileLocation != null && tempFileLocation.exists()) {
    -  250  9
                 LOGGER.log(Level.FINE, "Attempting to delete temporary files");
    -  251  9
                 final boolean success = FileUtils.delete(tempFileLocation);
    -  252  9
                 if (!success) {
    -  253  1
                     LOGGER.log(Level.WARNING,
    -  254   -
                             "Failed to delete some temporary files, see the log for more details");
    -  255   -
                 }
    -  256   -
             }
    -  257  10
         }
    -  258   -
     
    -  259   -
         /**
    -  260   -
          * Gathers evidence from the METADATA file.
    -  261   -
          *
    -  262   -
          * @param dependency the dependency being analyzed
    -  263   -
          * @param file a reference to the manifest/properties file
    -  264   -
          * @throws AnalysisException thrown when there is an error
    -  265   -
          */
    -  266   -
         private static void collectWheelMetadata(Dependency dependency, File file)
    -  267   -
                 throws AnalysisException {
    -  268  6
             final InternetHeaders headers = getManifestProperties(file);
    -  269  6
             addPropertyToEvidence(headers, dependency.getVersionEvidence(),
    -  270   -
                     "Version", Confidence.HIGHEST);
    -  271  6
             addPropertyToEvidence(headers, dependency.getProductEvidence(), "Name",
    -  272   -
                     Confidence.HIGHEST);
    -  273  6
             final String url = headers.getHeader("Home-page", null);
    -  274  6
             final EvidenceCollection vendorEvidence = dependency
    -  275   -
                     .getVendorEvidence();
    -  276  6
             if (StringUtils.isNotBlank(url)) {
    -  277  6
                 if (UrlStringUtils.isUrl(url)) {
    -  278  6
                     vendorEvidence.addEvidence(METADATA, "vendor", url,
    -  279   -
                             Confidence.MEDIUM);
    -  280   -
                 }
    -  281   -
             }
    -  282  6
             addPropertyToEvidence(headers, vendorEvidence, "Author", Confidence.LOW);
    -  283  6
             final String summary = headers.getHeader("Summary", null);
    -  284  6
             if (StringUtils.isNotBlank(summary)) {
    -  285  6
                 JarAnalyzer
    -  286   -
                         .addDescription(dependency, summary, METADATA, "summary");
    -  287   -
             }
    -  288  6
         }
    -  289   -
     
    -  290   -
         /**
    -  291   -
          * Adds a value to the evidence collection.
    -  292   -
          *
    -  293   -
          * @param headers the properties collection
    -  294   -
          * @param evidence the evidence collection to add the value
    -  295   -
          * @param property the property name
    -  296   -
          * @param confidence the confidence of the evidence
    -  297   -
          */
    -  298   -
         private static void addPropertyToEvidence(InternetHeaders headers,
    -  299   -
                 EvidenceCollection evidence, String property, Confidence confidence) {
    -  300  18
             final String value = headers.getHeader(property, null);
    -  301  18
             LOGGER.fine(String.format("Property: %s, Value: %s", property, value));
    -  302  18
             if (StringUtils.isNotBlank(value)) {
    -  303  18
                 evidence.addEvidence(METADATA, property, value, confidence);
    -  304   -
             }
    -  305  18
         }
    -  306   -
     
    -  307   -
         /**
    -  308   -
          * Returns a list of files that match the given filter, this does not recursively scan the directory.
    -  309   -
          *
    -  310   -
          * @param folder the folder to filter
    -  311   -
          * @param filter the filter to apply to the files in the directory
    -  312   -
          * @return the list of Files in the directory that match the provided filter
    -  313   -
          */
    -  314   -
         private static File getMatchingFile(File folder, FilenameFilter filter) {
    -  315  6
             File result = null;
    -  316  6
             final File[] matches = folder.listFiles(filter);
    -  317  6
             if (null != matches && 1 == matches.length) {
    -  318  6
                 result = matches[0];
    -  319   -
             }
    -  320  6
             return result;
    -  321   -
         }
    -  322   -
     
    -  323   -
         /**
    -  324   -
          * Reads the manifest entries from the provided file.
    -  325   -
          *
    -  326   -
          * @param manifest the manifest
    -  327   -
          * @return the manifest entries
    -  328   -
          */
    -  329   -
         private static InternetHeaders getManifestProperties(File manifest) {
    -  330  6
             final InternetHeaders result = new InternetHeaders();
    -  331  6
             if (null == manifest) {
    -  332  0
                 LOGGER.fine("Manifest file not found.");
    -  333  
             } else {
    -  334   -
                 try {
    -  335  6
                     result.load(new AutoCloseInputStream(new BufferedInputStream(
    -  336   -
                             new FileInputStream(manifest))));
    -  337  0
                 } catch (MessagingException e) {
    -  338  0
                     LOGGER.log(Level.WARNING, e.getMessage(), e);
    -  339  0
                 } catch (FileNotFoundException e) {
    -  340  0
                     LOGGER.log(Level.WARNING, e.getMessage(), e);
    -  341  6
                 }
    -  342   +  186  24
                 final String name = actualFile.getName();
    +  187  24
                 final boolean metadata = METADATA.equals(name);
    +  188  24
                 if (metadata || PKG_INFO.equals(name)) {
    +  189  24
                     final File parent = actualFile.getParentFile();
    +  190  24
                     final String parentName = parent.getName();
    +  191  24
                     dependency.setDisplayFileName(parentName + "/" + name);
    +  192  24
                     if (parent.isDirectory()
    +  193   +
                             && (metadata && parentName.endsWith(".dist-info")
    +  194   +
                             || parentName.endsWith(".egg-info") || "EGG-INFO"
    +  195   +
                             .equals(parentName))) {
    +  196  24
                         collectWheelMetadata(dependency, actualFile);
    +  197   +
                     }
    +  198   +
                 }
    +  199  
             }
    -  343  6
             return result;
    -  344   -
         }
    -  345   +  200  48
         }
    +  201  
     
    -  346   +  202  
         /**
    -  347   -
          * Retrieves the next temporary destingation directory for extracting an archive.
    -  348   +  203   +
          * Collects the meta data from an archive.
    +  204  
          *
    -  349   -
          * @return a directory
    -  350   -
          * @throws AnalysisException thrown if unable to create temporary directory
    -  351   +  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  
          */
    -  352   -
         private File getNextTempDirectory() throws AnalysisException {
    -  353   -
             File directory;
    -  354   +  210   +
         private void collectMetadataFromArchiveFormat(Dependency dependency,
    +  211   +
                 FilenameFilter folderFilter, FilenameFilter metadataFilter)
    +  212   +
                 throws AnalysisException {
    +  213  24
             final File temp = getNextTempDirectory();
    +  214  24
             LOGGER.debug("{} exists? {}", temp, temp.exists());
    +  215   +
             try {
    +  216  24
                 ExtractionUtil.extractFilesUsingFilter(
    +  217   +
                         new File(dependency.getActualFilePath()), temp,
    +  218   +
                         metadataFilter);
    +  219  0
             } catch (ExtractionException ex) {
    +  220  0
                 throw new AnalysisException(ex);
    +  221  24
             }
    +  222  
     
    -  355   -
             // getting an exception for some directories not being able to be
    -  356   -
             // created; might be because the directory already exists?
    -  357   -
             do {
    -  358  3
                 dirCount += 1;
    -  359  3
                 directory = new File(tempFileLocation, String.valueOf(dirCount));
    -  360  3
             } while (directory.exists());
    -  361  3
             if (!directory.mkdirs()) {
    -  362  0
                 throw new AnalysisException(String.format(
    -  363   -
                         "Unable to create temp directory '%s'.",
    -  364   -
                         directory.getAbsolutePath()));
    -  365   +  223  24
             collectWheelMetadata(
    +  224   +
                     dependency,
    +  225   +
                     getMatchingFile(getMatchingFile(temp, folderFilter),
    +  226   +
                             metadataFilter));
    +  227  24
         }
    +  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  64
             final File baseDir = Settings.getTempDirectory();
    +  237  64
             tempFileLocation = File.createTempFile("check", "tmp", baseDir);
    +  238  64
             if (!tempFileLocation.delete()) {
    +  239  0
                 final String msg = String.format(
    +  240   +
                         "Unable to delete temporary file '%s'.",
    +  241   +
                         tempFileLocation.getAbsolutePath());
    +  242  0
                 throw new AnalysisException(msg);
    +  243  
             }
    -  366  3
             return directory;
    -  367   +  244  64
             if (!tempFileLocation.mkdirs()) {
    +  245  0
                 final String msg = String.format(
    +  246   +
                         "Unable to create directory '%s'.",
    +  247   +
                         tempFileLocation.getAbsolutePath());
    +  248  0
                 throw new AnalysisException(msg);
    +  249   +
             }
    +  250  64
         }
    +  251   +
     
    +  252   +
         /**
    +  253   +
          * Deletes any files extracted from the Wheel during analysis.
    +  254   +
          */
    +  255   +
         @Override
    +  256   +
         public void close() {
    +  257  72
             if (tempFileLocation != null && tempFileLocation.exists()) {
    +  258  64
                 LOGGER.debug("Attempting to delete temporary files");
    +  259  64
                 final boolean success = FileUtils.delete(tempFileLocation);
    +  260  64
                 if (!success) {
    +  261  8
                     LOGGER.warn(
    +  262   +
                             "Failed to delete some temporary files, see the log for more details");
    +  263   +
                 }
    +  264   +
             }
    +  265  72
         }
    +  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   +
          * @throws AnalysisException thrown when there is an error
    +  273   +
          */
    +  274   +
         private static void collectWheelMetadata(Dependency dependency, File file)
    +  275   +
                 throws AnalysisException {
    +  276  48
             final InternetHeaders headers = getManifestProperties(file);
    +  277  48
             addPropertyToEvidence(headers, dependency.getVersionEvidence(),
    +  278   +
                     "Version", Confidence.HIGHEST);
    +  279  48
             addPropertyToEvidence(headers, dependency.getProductEvidence(), "Name",
    +  280   +
                     Confidence.HIGHEST);
    +  281  48
             final String url = headers.getHeader("Home-page", null);
    +  282  48
             final EvidenceCollection vendorEvidence = dependency
    +  283   +
                     .getVendorEvidence();
    +  284  48
             if (StringUtils.isNotBlank(url)) {
    +  285  48
                 if (UrlStringUtils.isUrl(url)) {
    +  286  48
                     vendorEvidence.addEvidence(METADATA, "vendor", url,
    +  287   +
                             Confidence.MEDIUM);
    +  288   +
                 }
    +  289   +
             }
    +  290  48
             addPropertyToEvidence(headers, vendorEvidence, "Author", Confidence.LOW);
    +  291  48
             final String summary = headers.getHeader("Summary", null);
    +  292  48
             if (StringUtils.isNotBlank(summary)) {
    +  293  48
                 JarAnalyzer
    +  294   +
                         .addDescription(dependency, summary, METADATA, "summary");
    +  295   +
             }
    +  296  48
         }
    +  297   +
     
    +  298   +
         /**
    +  299   +
          * Adds a value to the evidence collection.
    +  300   +
          *
    +  301   +
          * @param headers the properties collection
    +  302   +
          * @param evidence the evidence collection to add the value
    +  303   +
          * @param property the property name
    +  304   +
          * @param confidence the confidence of the evidence
    +  305   +
          */
    +  306   +
         private static void addPropertyToEvidence(InternetHeaders headers,
    +  307   +
                 EvidenceCollection evidence, String property, Confidence confidence) {
    +  308  144
             final String value = headers.getHeader(property, null);
    +  309  144
             LOGGER.debug("Property: {}, Value: {}", property, value);
    +  310  144
             if (StringUtils.isNotBlank(value)) {
    +  311  144
                 evidence.addEvidence(METADATA, property, value, confidence);
    +  312   +
             }
    +  313  144
         }
    +  314   +
     
    +  315   +
         /**
    +  316   +
          * Returns a list of files that match the given filter, this does not recursively scan the directory.
    +  317   +
          *
    +  318   +
          * @param folder the folder to filter
    +  319   +
          * @param filter the filter to apply to the files in the directory
    +  320   +
          * @return the list of Files in the directory that match the provided filter
    +  321   +
          */
    +  322   +
         private static File getMatchingFile(File folder, FilenameFilter filter) {
    +  323  48
             File result = null;
    +  324  48
             final File[] matches = folder.listFiles(filter);
    +  325  48
             if (null != matches && 1 == matches.length) {
    +  326  48
                 result = matches[0];
    +  327   +
             }
    +  328  48
             return result;
    +  329  
         }
    -  368   +  330   +
     
    +  331   +
         /**
    +  332   +
          * Reads the manifest entries from the provided file.
    +  333   +
          *
    +  334   +
          * @param manifest the manifest
    +  335   +
          * @return the manifest entries
    +  336   +
          */
    +  337   +
         private static InternetHeaders getManifestProperties(File manifest) {
    +  338  48
             final InternetHeaders result = new InternetHeaders();
    +  339  48
             if (null == manifest) {
    +  340  0
                 LOGGER.debug("Manifest file not found.");
    +  341   +
             } else {
    +  342   +
                 try {
    +  343  48
                     result.load(new AutoCloseInputStream(new BufferedInputStream(
    +  344   +
                             new FileInputStream(manifest))));
    +  345  0
                 } catch (MessagingException e) {
    +  346  0
                     LOGGER.warn(e.getMessage(), e);
    +  347  0
                 } catch (FileNotFoundException e) {
    +  348  0
                     LOGGER.warn(e.getMessage(), e);
    +  349  48
                 }
    +  350   +
             }
    +  351  48
             return result;
    +  352   +
         }
    +  353   +
     
    +  354   +
         /**
    +  355   +
          * Retrieves the next temporary destingation directory for extracting an archive.
    +  356   +
          *
    +  357   +
          * @return a directory
    +  358   +
          * @throws AnalysisException thrown if unable to create temporary directory
    +  359   +
          */
    +  360   +
         private File getNextTempDirectory() throws AnalysisException {
    +  361   +
             File directory;
    +  362   +
     
    +  363   +
             // getting an exception for some directories not being able to be
    +  364   +
             // created; might be because the directory already exists?
    +  365   +
             do {
    +  366  24
                 dirCount += 1;
    +  367  24
                 directory = new File(tempFileLocation, String.valueOf(dirCount));
    +  368  24
             } while (directory.exists());
    +  369  24
             if (!directory.mkdirs()) {
    +  370  0
                 throw new AnalysisException(String.format(
    +  371   +
                         "Unable to create temp directory '%s'.",
    +  372   +
                         directory.getAbsolutePath()));
    +  373   +
             }
    +  374  24
             return directory;
    +  375   +
         }
    +  376  
     }
    - + 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 43ba769d4..a7f18469e 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
    90%
    64/71
    77%
    14/18
    2.091
    PythonPackageAnalyzer
    90%
    63/70
    77%
    14/18
    2.091
     
    @@ -56,49 +56,49 @@  19  
     
     20   -
     import java.io.File;
    -  21   -
     import java.io.FileFilter;
    -  22   -
     import java.io.IOException;
    -  23   -
     import java.net.MalformedURLException;
    -  24   -
     import java.util.ArrayList;
    -  25   -
     import java.util.Collections;
    -  26   -
     import java.util.List;
    -  27   -
     import java.util.Set;
    -  28   -
     import java.util.logging.Logger;
    -  29   -
     import java.util.regex.Matcher;
    -  30   -
     import java.util.regex.Pattern;
    -  31   -
     
    -  32  
     import org.apache.commons.io.FileUtils;
    -  33   +  21  
     import org.apache.commons.io.filefilter.NameFileFilter;
    -  34   +  22  
     import org.apache.commons.io.filefilter.SuffixFileFilter;
    -  35   +  23  
     import org.owasp.dependencycheck.Engine;
    -  36   +  24  
     import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
    -  37   +  25  
     import org.owasp.dependencycheck.dependency.Confidence;
    -  38   +  26  
     import org.owasp.dependencycheck.dependency.Dependency;
    -  39   +  27  
     import org.owasp.dependencycheck.dependency.EvidenceCollection;
    -  40   +  28   +
     import org.owasp.dependencycheck.utils.FileFilterBuilder;
    +  29  
     import org.owasp.dependencycheck.utils.Settings;
    -  41   +  30  
     import org.owasp.dependencycheck.utils.UrlStringUtils;
    +  31   +
     import org.slf4j.Logger;
    +  32   +
     import org.slf4j.LoggerFactory;
    +  33   +
     
    +  34   +
     import java.io.File;
    +  35   +
     import java.io.FileFilter;
    +  36   +
     import java.io.IOException;
    +  37   +
     import java.net.MalformedURLException;
    +  38   +
     import java.util.ArrayList;
    +  39   +
     import java.util.List;
    +  40   +
     import java.util.regex.Matcher;
    +  41   +
     import java.util.regex.Pattern;
     42  
     
     43   @@ -111,7 +111,7 @@
      * @author Dale Visser <dvisser@ida.org>
     47  
      */
    -  48  6
     public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer {
    +  48  48
     public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer {
     49  
     
     50   @@ -132,9 +132,9 @@
          * The logger.
     58  
          */
    -  59  1
         private static final Logger LOGGER = Logger
    +  59  8
         private static final Logger LOGGER = LoggerFactory
     60   -
                 .getLogger(PythonDistributionAnalyzer.class.getName());
    +
                 .getLogger(PythonPackageAnalyzer.class);
     61  
     
     62   @@ -143,457 +143,466 @@
          * Filename extensions for files to be analyzed.
     64  
          */
    -  65  1
         private static final Set<String> EXTENSIONS = Collections
    +  65   +
         private static final String EXTENSIONS = "py";
     66   -
                 .unmodifiableSet(Collections.singleton("py"));
    +
     
     67   -
     
    +
         /**
     68   -
         /**
    -  69  
          * Pattern for matching the module docstring in a source file.
    -  70   +  69  
          */
    -  71  1
         private static final Pattern MODULE_DOCSTRING = Pattern.compile(
    -  72   +  70  8
         private static final Pattern MODULE_DOCSTRING = Pattern.compile(
    +  71  
                 "^(['\\\"]{3})(.*?)\\1", REGEX_OPTIONS);
    +  72   +
     
     73   -
     
    +
         /**
     74   -
         /**
    -  75  
          * Matches assignments to version variables in Python source code.
    -  76   +  75  
          */
    -  77  1
         private static final Pattern VERSION_PATTERN = Pattern.compile(
    -  78   +  76  8
         private static final Pattern VERSION_PATTERN = Pattern.compile(
    +  77  
                 "\\b(__)?version(__)? *= *(['\"]+)(\\d+\\.\\d+.*?)\\3",
    -  79   +  78  
                 REGEX_OPTIONS);
    +  79   +
     
     80   -
     
    +
         /**
     81   -
         /**
    -  82  
          * Matches assignments to title variables in Python source code.
    -  83   +  82  
          */
    -  84  1
         private static final Pattern TITLE_PATTERN = compileAssignPattern("title");
    +  83  8
         private static final Pattern TITLE_PATTERN = compileAssignPattern("title");
    +  84   +
     
     85   -
     
    +
         /**
     86   -
         /**
    -  87  
          * Matches assignments to summary variables in Python source code.
    -  88   +  87  
          */
    -  89  1
         private static final Pattern SUMMARY_PATTERN = compileAssignPattern("summary");
    +  88  8
         private static final Pattern SUMMARY_PATTERN = compileAssignPattern("summary");
    +  89   +
     
     90   -
     
    +
         /**
     91   -
         /**
    -  92  
          * Matches assignments to URL/URL variables in Python source code.
    -  93   +  92  
          */
    -  94  1
         private static final Pattern URI_PATTERN = compileAssignPattern("ur[il]");
    +  93  8
         private static final Pattern URI_PATTERN = compileAssignPattern("ur[il]");
    +  94   +
     
     95   -
     
    +
         /**
     96   -
         /**
    -  97  
          * Matches assignments to home page variables in Python source code.
    -  98   +  97  
          */
    -  99  1
         private static final Pattern HOMEPAGE_PATTERN = compileAssignPattern("home_?page");
    +  98  8
         private static final Pattern HOMEPAGE_PATTERN = compileAssignPattern("home_?page");
    +  99   +
     
     100   -
     
    +
         /**
     101   -
         /**
    -  102  
          * Matches assignments to author variables in Python source code.
    -  103   +  102  
          */
    -  104  1
         private static final Pattern AUTHOR_PATTERN = compileAssignPattern("author");
    +  103  8
         private static final Pattern AUTHOR_PATTERN = compileAssignPattern("author");
    +  104   +
     
     105   -
     
    +
         /**
     106   -
         /**
    -  107  
          * Filter that detects files named "__init__.py".
    -  108   +  107  
          */
    -  109  1
         private static final FileFilter INIT_PY_FILTER = new NameFileFilter("__init__.py");
    +  108  8
         private static final FileFilter INIT_PY_FILTER = new NameFileFilter("__init__.py");
    +  109   +
     
     110   -
     
    +
         /**
     111   -
         /**
    -  112  
          * The file filter for python files.
    -  113   +  112  
          */
    -  114  1
         private static final FileFilter PY_FILTER = new SuffixFileFilter(".py");
    +  113  8
         private static final FileFilter PY_FILTER = new SuffixFileFilter(".py");
    +  114   +
     
     115   -
     
    +
         /**
     116   -
         /**
    -  117  
          * Returns the name of the Python Package Analyzer.
    +  117   +
          *
     118   -
          *
    -  119  
          * @return the name of the analyzer
    +  119   +
          */
     120   -
          */
    +
         @Override
     121   -
         @Override
    -  122  
         public String getName() {
    -  123  5
             return "Python Package Analyzer";
    +  122  40
             return "Python Package Analyzer";
    +  123   +
         }
     124   -
         }
    +
     
     125   -
     
    +
         /**
     126   -
         /**
    -  127  
          * Tell that we are used for information collection.
    +  127   +
          *
     128   -
          *
    -  129  
          * @return INFORMATION_COLLECTION
    +  129   +
          */
     130   -
          */
    +
         @Override
     131   -
         @Override
    -  132  
         public AnalysisPhase getAnalysisPhase() {
    -  133  1
             return AnalysisPhase.INFORMATION_COLLECTION;
    +  132  16
             return AnalysisPhase.INFORMATION_COLLECTION;
    +  133   +
         }
     134   -
         }
    +
     
     135   -
     
    +
         /**
     136   -
         /**
    +
          * The file filter used to determine which files this analyzer supports.
     137   -
          * Returns the set of supported file extensions.
    -  138   -
          *
    +
          */
    +  138  8
         private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(EXTENSIONS).build();
     139   -
          * @return the set of supported file extensions
    +
     
     140   -
          */
    +
         /**
     141   -
         @Override
    +
          * Returns the FileFilter
     142   -
         protected Set<String> getSupportedExtensions() {
    -  143  850
             return EXTENSIONS;
    +
          *
    +  143   +
          * @return the FileFilter
     144   -
         }
    +
          */
     145   -
     
    -  146   -
         /**
    -  147   -
          * No-op initializer implementation.
    -  148   -
          *
    -  149   -
          * @throws Exception never thrown
    -  150   -
          */
    -  151  
         @Override
    -  152   -
         protected void initializeFileTypeAnalyzer() throws Exception {
    -  153   -
             // Nothing to do here.
    -  154  4
         }
    -  155   +  146   +
         protected FileFilter getFileFilter() {
    +  147  6832
             return FILTER;
    +  148   +
         }
    +  149  
     
    -  156   +  150  
         /**
    -  157   -
          * Utility function to create a regex pattern matcher.
    -  158   +  151   +
          * No-op initializer implementation.
    +  152  
          *
    -  159   -
          * @param name the value to use when constructing the assignment pattern
    -  160   -
          * @return the compiled Pattern
    -  161   +  153   +
          * @throws Exception never thrown
    +  154  
          */
    +  155   +
         @Override
    +  156   +
         protected void initializeFileTypeAnalyzer() throws Exception {
    +  157   +
             // Nothing to do here.
    +  158  24
         }
    +  159   +
     
    +  160   +
         /**
    +  161   +
          * Utility function to create a regex pattern matcher.
     162   -
         private static Pattern compileAssignPattern(String name) {
    -  163  5
             return Pattern.compile(
    +
          *
    +  163   +
          * @param name the value to use when constructing the assignment pattern
     164   -
                     String.format("\\b(__)?%s(__)?\\b *= *(['\"]+)(.*?)\\3", name),
    +
          * @return the compiled Pattern
     165   -
                     REGEX_OPTIONS);
    +
          */
     166   -
         }
    -  167   -
     
    +
         private static Pattern compileAssignPattern(String name) {
    +  167  40
             return Pattern.compile(
     168   -
         /**
    +
                     String.format("\\b(__)?%s(__)?\\b *= *(['\"]+)(.*?)\\3", name),
     169   -
          * Analyzes python packages and adds evidence to the dependency.
    +
                     REGEX_OPTIONS);
     170   -
          *
    +
         }
     171   -
          * @param dependency the dependency being analyzed
    +
     
     172   -
          * @param engine the engine being used to perform the scan
    +
         /**
     173   -
          * @throws AnalysisException thrown if there is an unrecoverable error analyzing the dependency
    +
          * Analyzes python packages and adds evidence to the dependency.
     174   -
          */
    +
          *
     175   -
         @Override
    +
          * @param dependency the dependency being analyzed
     176   -
         protected void analyzeFileType(Dependency dependency, Engine engine)
    +
          * @param engine the engine being used to perform the scan
     177   -
                 throws AnalysisException {
    -  178  1
             final File file = dependency.getActualFile();
    -  179  1
             final File parent = file.getParentFile();
    -  180  1
             final String parentName = parent.getName();
    -  181  1
             boolean found = false;
    -  182  1
             if (INIT_PY_FILTER.accept(file)) {
    -  183  4
                 for (final File sourcefile : parent.listFiles(PY_FILTER)) {
    -  184  3
                     found |= analyzeFileContents(dependency, sourcefile);
    -  185   -
                 }
    -  186   -
             }
    -  187  1
             if (found) {
    -  188  1
                 dependency.setDisplayFileName(parentName + "/__init__.py");
    -  189  1
                 dependency.getProductEvidence().addEvidence(file.getName(),
    -  190   -
                         "PackageName", parentName, Confidence.MEDIUM);
    -  191   -
             } else {
    -  192   -
                 // copy, alter and set in case some other thread is iterating over
    -  193  0
                 final List<Dependency> deps = new ArrayList<Dependency>(
    -  194   -
                         engine.getDependencies());
    -  195  0
                 deps.remove(dependency);
    -  196  0
                 engine.setDependencies(deps);
    -  197   -
             }
    -  198  1
         }
    -  199   -
     
    -  200   -
         /**
    -  201   -
          * This should gather information from leading docstrings, file comments, and assignments to __version__, __title__,
    -  202   -
          * __summary__, __uri__, __url__, __home*page__, __author__, and their all caps equivalents.
    -  203   -
          *
    -  204   -
          * @param dependency the dependency being analyzed
    -  205   -
          * @param file the file name to analyze
    -  206   -
          * @return whether evidence was found
    -  207   -
          * @throws AnalysisException thrown if there is an unrecoverable error
    -  208   +
          * @throws AnalysisException thrown if there is an unrecoverable error analyzing the dependency
    +  178  
          */
    -  209   -
         private boolean analyzeFileContents(Dependency dependency, File file)
    -  210   -
                 throws AnalysisException {
    -  211  3
             String contents = "";
    -  212   -
             try {
    -  213  3
                 contents = FileUtils.readFileToString(file).trim();
    -  214  0
             } catch (IOException e) {
    -  215  0
                 throw new AnalysisException(
    -  216   -
                         "Problem occured while reading dependency file.", e);
    -  217  3
             }
    -  218  3
             boolean found = false;
    -  219  3
             if (!contents.isEmpty()) {
    -  220  3
                 final String source = file.getName();
    -  221  3
                 found = gatherEvidence(VERSION_PATTERN, contents, source,
    -  222   -
                         dependency.getVersionEvidence(), "SourceVersion",
    -  223   -
                         Confidence.MEDIUM);
    -  224  3
                 found |= addSummaryInfo(dependency, SUMMARY_PATTERN, 4, contents,
    -  225   -
                         source, "summary");
    -  226  3
                 if (INIT_PY_FILTER.accept(file)) {
    -  227  1
                     found |= addSummaryInfo(dependency, MODULE_DOCSTRING, 2,
    -  228   -
                             contents, source, "docstring");
    -  229   -
                 }
    -  230  3
                 found |= gatherEvidence(TITLE_PATTERN, contents, source,
    -  231   -
                         dependency.getProductEvidence(), "SourceTitle",
    -  232   -
                         Confidence.LOW);
    -  233  3
                 final EvidenceCollection vendorEvidence = dependency
    -  234   -
                         .getVendorEvidence();
    -  235  3
                 found |= gatherEvidence(AUTHOR_PATTERN, contents, source,
    -  236   -
                         vendorEvidence, "SourceAuthor", Confidence.MEDIUM);
    -  237   -
                 try {
    -  238  3
                     found |= gatherHomePageEvidence(URI_PATTERN, vendorEvidence,
    -  239   -
                             source, "URL", contents);
    -  240  3
                     found |= gatherHomePageEvidence(HOMEPAGE_PATTERN,
    -  241   -
                             vendorEvidence, source, "HomePage", contents);
    -  242  0
                 } catch (MalformedURLException e) {
    -  243  0
                     LOGGER.warning(e.getMessage());
    -  244  3
                 }
    -  245   -
             }
    -  246  3
             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  4
             final Matcher matcher = pattern.matcher(contents);
    -  263  4
             final boolean found = matcher.find();
    -  264  4
             if (found) {
    -  265  1
                 JarAnalyzer.addDescription(dependency, matcher.group(group),
    -  266   -
                         source, key);
    -  267   -
             }
    -  268  4
             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   -
          * @throws MalformedURLException thrown if the URL is malformed
    -  281   -
          */
    -  282   -
         private boolean gatherHomePageEvidence(Pattern pattern,
    -  283   -
                 EvidenceCollection evidence, String source, String name,
    -  284   -
                 String contents) throws MalformedURLException {
    -  285  6
             final Matcher matcher = pattern.matcher(contents);
    -  286  6
             boolean found = false;
    -  287  6
             if (matcher.find()) {
    -  288  1
                 final String url = matcher.group(4);
    -  289  1
                 if (UrlStringUtils.isUrl(url)) {
    -  290  1
                     found = true;
    -  291  1
                     evidence.addEvidence(source, name, url, Confidence.MEDIUM);
    -  292   -
                 }
    -  293   -
             }
    -  294  6
             return found;
    -  295   -
         }
    -  296   -
     
    -  297   -
         /**
    -  298   -
          * Gather evidence from a Python source file usin the given string 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  9
             final Matcher matcher = pattern.matcher(contents);
    -  312  9
             final boolean found = matcher.find();
    -  313  9
             if (found) {
    -  314  3
                 evidence.addEvidence(source, name, matcher.group(4), confidence);
    -  315   -
             }
    -  316  9
             return found;
    -  317   -
         }
    -  318   -
     
    -  319   +  179  
         @Override
    -  320   -
         protected String getAnalyzerEnabledSettingKey() {
    -  321  6
             return Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED;
    -  322   +  180   +
         protected void analyzeFileType(Dependency dependency, Engine engine)
    +  181   +
                 throws AnalysisException {
    +  182  8
             final File file = dependency.getActualFile();
    +  183  8
             final File parent = file.getParentFile();
    +  184  8
             final String parentName = parent.getName();
    +  185  8
             boolean found = false;
    +  186  8
             if (INIT_PY_FILTER.accept(file)) {
    +  187  32
                 for (final File sourcefile : parent.listFiles(PY_FILTER)) {
    +  188  24
                     found |= analyzeFileContents(dependency, sourcefile);
    +  189   +
                 }
    +  190   +
             }
    +  191  8
             if (found) {
    +  192  8
                 dependency.setDisplayFileName(parentName + "/__init__.py");
    +  193  8
                 dependency.getProductEvidence().addEvidence(file.getName(),
    +  194   +
                         "PackageName", parentName, Confidence.MEDIUM);
    +  195   +
             } else {
    +  196   +
                 // copy, alter and set in case some other thread is iterating over
    +  197  0
                 final List<Dependency> deps = new ArrayList<Dependency>(
    +  198   +
                         engine.getDependencies());
    +  199  0
                 deps.remove(dependency);
    +  200  0
                 engine.setDependencies(deps);
    +  201   +
             }
    +  202  8
         }
    +  203   +
     
    +  204   +
         /**
    +  205   +
          * This should gather information from leading docstrings, file comments, and assignments to __version__, __title__,
    +  206   +
          * __summary__, __uri__, __url__, __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  24
                 contents = FileUtils.readFileToString(file).trim();
    +  218  0
             } catch (IOException e) {
    +  219  0
                 throw new AnalysisException(
    +  220   +
                         "Problem occurred while reading dependency file.", e);
    +  221  24
             }
    +  222  24
             boolean found = false;
    +  223  24
             if (!contents.isEmpty()) {
    +  224  24
                 final String source = file.getName();
    +  225  24
                 found = gatherEvidence(VERSION_PATTERN, contents, source,
    +  226   +
                         dependency.getVersionEvidence(), "SourceVersion",
    +  227   +
                         Confidence.MEDIUM);
    +  228  24
                 found |= addSummaryInfo(dependency, SUMMARY_PATTERN, 4, contents,
    +  229   +
                         source, "summary");
    +  230  24
                 if (INIT_PY_FILTER.accept(file)) {
    +  231  8
                     found |= addSummaryInfo(dependency, MODULE_DOCSTRING, 2,
    +  232   +
                             contents, source, "docstring");
    +  233   +
                 }
    +  234  24
                 found |= gatherEvidence(TITLE_PATTERN, contents, source,
    +  235   +
                         dependency.getProductEvidence(), "SourceTitle",
    +  236   +
                         Confidence.LOW);
    +  237  24
                 final EvidenceCollection vendorEvidence = dependency
    +  238   +
                         .getVendorEvidence();
    +  239  24
                 found |= gatherEvidence(AUTHOR_PATTERN, contents, source,
    +  240   +
                         vendorEvidence, "SourceAuthor", Confidence.MEDIUM);
    +  241   +
                 try {
    +  242  24
                     found |= gatherHomePageEvidence(URI_PATTERN, vendorEvidence,
    +  243   +
                             source, "URL", contents);
    +  244  24
                     found |= gatherHomePageEvidence(HOMEPAGE_PATTERN,
    +  245   +
                             vendorEvidence, source, "HomePage", contents);
    +  246  0
                 } catch (MalformedURLException e) {
    +  247  0
                     LOGGER.warn(e.getMessage());
    +  248  24
                 }
    +  249   +
             }
    +  250  24
             return found;
    +  251  
         }
    +  252   +
     
    +  253   +
         /**
    +  254   +
          * Adds summary information to the dependency
    +  255   +
          *
    +  256   +
          * @param dependency the dependency being analyzed
    +  257   +
          * @param pattern the pattern used to perform analysis
    +  258   +
          * @param group the group from the pattern that indicates the data to use
    +  259   +
          * @param contents the data being analyzed
    +  260   +
          * @param source the source name to use when recording the evidence
    +  261   +
          * @param key the key name to use when recording the evidence
    +  262   +
          * @return true if evidence was collected; otherwise false
    +  263   +
          */
    +  264   +
         private boolean addSummaryInfo(Dependency dependency, Pattern pattern,
    +  265   +
                 int group, String contents, String source, String key) {
    +  266  32
             final Matcher matcher = pattern.matcher(contents);
    +  267  32
             final boolean found = matcher.find();
    +  268  32
             if (found) {
    +  269  8
                 JarAnalyzer.addDescription(dependency, matcher.group(group),
    +  270   +
                         source, key);
    +  271   +
             }
    +  272  32
             return found;
    +  273   +
         }
    +  274   +
     
    +  275   +
         /**
    +  276   +
          * Collects evidence from the home page URL.
    +  277   +
          *
    +  278   +
          * @param pattern the pattern to match
    +  279   +
          * @param evidence the evidence collection to add the evidence to
    +  280   +
          * @param source the source of the evidence
    +  281   +
          * @param name the name of the evidence
    +  282   +
          * @param contents the home page URL
    +  283   +
          * @return true if evidence was collected; otherwise false
    +  284   +
          * @throws MalformedURLException thrown if the URL is malformed
    +  285   +
          */
    +  286   +
         private boolean gatherHomePageEvidence(Pattern pattern,
    +  287   +
                 EvidenceCollection evidence, String source, String name,
    +  288   +
                 String contents) throws MalformedURLException {
    +  289  48
             final Matcher matcher = pattern.matcher(contents);
    +  290  48
             boolean found = false;
    +  291  48
             if (matcher.find()) {
    +  292  8
                 final String url = matcher.group(4);
    +  293  8
                 if (UrlStringUtils.isUrl(url)) {
    +  294  8
                     found = true;
    +  295  8
                     evidence.addEvidence(source, name, url, Confidence.MEDIUM);
    +  296   +
                 }
    +  297   +
             }
    +  298  48
             return found;
    +  299   +
         }
    +  300   +
     
    +  301   +
         /**
    +  302   +
          * Gather evidence from a Python source file usin the given string assignment regex pattern.
    +  303   +
          *
    +  304   +
          * @param pattern to scan contents with
    +  305   +
          * @param contents of Python source file
    +  306   +
          * @param source for storing evidence
    +  307   +
          * @param evidence to store evidence in
    +  308   +
          * @param name of evidence
    +  309   +
          * @param confidence in evidence
    +  310   +
          * @return whether evidence was found
    +  311   +
          */
    +  312   +
         private boolean gatherEvidence(Pattern pattern, String contents,
    +  313   +
                 String source, EvidenceCollection evidence, String name,
    +  314   +
                 Confidence confidence) {
    +  315  72
             final Matcher matcher = pattern.matcher(contents);
    +  316  72
             final boolean found = matcher.find();
    +  317  72
             if (found) {
    +  318  24
                 evidence.addEvidence(source, name, matcher.group(4), confidence);
    +  319   +
             }
    +  320  72
             return found;
    +  321   +
         }
    +  322   +
     
     323   +
         @Override
    +  324   +
         protected String getAnalyzerEnabledSettingKey() {
    +  325  48
             return Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED;
    +  326   +
         }
    +  327  
     }
    - + 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 ea51cbc35..59678a44c 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  2
     public class VulnerabilitySuppressionAnalyzer extends AbstractSuppressionAnalyzer {
    +  31  24
     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  8
         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  1
             return ANALYSIS_PHASE;
    +  60  16
             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  16
             if (getRules() == null || getRules().size() <= 0) {
     68  0
                 return;
     69  
             }
     70  
     
    -  71  2
             for (final SuppressionRule rule : getRules()) {
    -  72  34
                 rule.process(dependency);
    -  73  34
             }
    -  74  2
         }
    +  71  16
             for (final SuppressionRule rule : getRules()) {
    +  72  304
                 rule.process(dependency);
    +  73  304
             }
    +  74  16
         }
     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 0f80758fa..cc3a71387 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  8
             super(msg);
    +  46  8
         }
     47  
     
     48   @@ -143,6 +143,6 @@
     }
    - + 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 6f071d6e7..760af0743 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 2290acaa8..154382bc6 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 @@ -12,7 +12,7 @@
     
    - +
    Classes in this File Line Coverage Branch Coverage Complexity
    CentralSearch
    83%
    51/61
    83%
    20/24
    10
    CentralSearch
    85%
    51/60
    83%
    20/24
    10
     
    @@ -68,227 +68,228 @@  25  
     import java.util.List;
     26   -
     import java.util.logging.Logger;
    -  27  
     import javax.xml.parsers.DocumentBuilder;
    -  28   +  27  
     import javax.xml.parsers.DocumentBuilderFactory;
    -  29   +  28  
     import javax.xml.xpath.XPath;
    -  30   +  29  
     import javax.xml.xpath.XPathConstants;
    -  31   +  30  
     import javax.xml.xpath.XPathFactory;
    -  32   +  31  
     import org.owasp.dependencycheck.data.nexus.MavenArtifact;
    -  33   +  32  
     import org.owasp.dependencycheck.utils.Settings;
    -  34   +  33  
     import org.owasp.dependencycheck.utils.URLConnectionFactory;
    +  34   +
     import org.slf4j.Logger;
     35   -
     import org.w3c.dom.Document;
    +
     import org.slf4j.LoggerFactory;
     36   -
     import org.w3c.dom.NodeList;
    +
     import org.w3c.dom.Document;
     37   -
     
    +
     import org.w3c.dom.NodeList;
     38   -
     /**
    +
     
     39   -
      * Class of methods to search Maven Central via Central.
    +
     /**
     40   -
      *
    +
      * Class of methods to search Maven Central via Central.
     41   -
      * @author colezlaw
    +
      *
     42   -
      */
    +
      * @author colezlaw
     43   -
     public class CentralSearch {
    +
      */
     44   -
     
    +
     public class CentralSearch {
     45   -
         /**
    +
     
     46   -
          * The URL for the Central service
    +
         /**
     47   -
          */
    +
          * The URL for the Central service
     48   -
         private final URL rootURL;
    +
          */
     49   -
     
    +
         private final URL rootURL;
     50   -
         /**
    +
     
     51   -
          * Whether to use the Proxy when making requests
    +
         /**
     52   -
          */
    +
          * Whether to use the Proxy when making requests
     53   -
         private boolean useProxy;
    +
          */
     54   -
     
    +
         private boolean useProxy;
     55   -
         /**
    +
     
     56   -
          * Used for logging.
    +
         /**
     57   +
          * Used for logging.
    +  58  
          */
    -  58  1
         private static final Logger LOGGER = Logger.getLogger(CentralSearch.class.getName());
    -  59   -
     
    +  59  8
         private static final Logger LOGGER = LoggerFactory.getLogger(CentralSearch.class);
     60   -
         /**
    +
     
     61   -
          * Creates a NexusSearch for the given repository URL.
    -  62   -
          *
    -  63   -
          * @param rootURL the URL of the repository on which searches should execute. Only parameters are added to this (so it should
    -  64   -
          * end in /select)
    -  65   -
          */
    -  66  5
         public CentralSearch(URL rootURL) {
    -  67  5
             this.rootURL = rootURL;
    -  68  5
             if (null != Settings.getString(Settings.KEYS.PROXY_SERVER)) {
    -  69  0
                 useProxy = true;
    -  70  0
                 LOGGER.fine("Using proxy");
    -  71   -
             } else {
    -  72  5
                 useProxy = false;
    -  73  5
                 LOGGER.fine("Not using proxy");
    -  74   -
             }
    -  75  5
         }
    -  76   -
     
    -  77  
         /**
    -  78   -
          * Searches the configured Central URL for the given sha1 hash. If the artifact is found, a <code>MavenArtifact</code> is
    -  79   -
          * populated with the GAV.
    -  80   +  62   +
          * Creates a NexusSearch for the given repository URL.
    +  63  
          *
    -  81   -
          * @param sha1 the SHA-1 hash string for which to search
    -  82   -
          * @return the populated Maven GAV.
    -  83   -
          * @throws IOException if it's unable to connect to the specified repository or if the specified artifact is not found.
    -  84   +  64   +
          * @param rootURL the URL of the repository on which searches should execute. Only parameters are added to this (so it should
    +  65   +
          * end in /select)
    +  66  
          */
    -  85   -
         public List<MavenArtifact> searchSha1(String sha1) throws IOException {
    -  86  5
             if (null == sha1 || !sha1.matches("^[0-9A-Fa-f]{40}$")) {
    -  87  2
                 throw new IllegalArgumentException("Invalid SHA1 format");
    -  88   +  67  40
         public CentralSearch(URL rootURL) {
    +  68  40
             this.rootURL = rootURL;
    +  69  40
             if (null != Settings.getString(Settings.KEYS.PROXY_SERVER)) {
    +  70  0
                 useProxy = true;
    +  71  0
                 LOGGER.debug("Using proxy");
    +  72   +
             } else {
    +  73  40
                 useProxy = false;
    +  74  40
                 LOGGER.debug("Not using proxy");
    +  75  
             }
    +  76  40
         }
    +  77   +
     
    +  78   +
         /**
    +  79   +
          * Searches the configured Central URL for the given sha1 hash. If the artifact is found, a <code>MavenArtifact</code> is
    +  80   +
          * populated with the GAV.
    +  81   +
          *
    +  82   +
          * @param sha1 the SHA-1 hash string for which to search
    +  83   +
          * @return the populated Maven GAV.
    +  84   +
          * @throws IOException if it's unable to connect to the specified repository or if the specified artifact is not found.
    +  85   +
          */
    +  86   +
         public List<MavenArtifact> searchSha1(String sha1) throws IOException {
    +  87  40
             if (null == sha1 || !sha1.matches("^[0-9A-Fa-f]{40}$")) {
    +  88  16
                 throw new IllegalArgumentException("Invalid SHA1 format");
     89   +
             }
    +  90  
     
    -  90  3
             final URL url = new URL(rootURL + String.format("?q=1:\"%s\"&wt=xml", sha1));
    -  91   -
     
    -  92  3
             LOGGER.fine(String.format("Searching Central url %s", url.toString()));
    -  93   +  91  24
             final URL url = new URL(rootURL + String.format("?q=1:\"%s\"&wt=xml", sha1));
    +  92  
     
    +  93  24
             LOGGER.debug("Searching Central url {}", url.toString());
     94   -
             // Determine if we need to use a proxy. The rules:
    +
     
     95   -
             // 1) If the proxy is set, AND the setting is set to true, use the proxy
    +
             // Determine if we need to use a proxy. The rules:
     96   -
             // 2) Otherwise, don't use the proxy (either the proxy isn't configured,
    +
             // 1) If the proxy is set, AND the setting is set to true, use the proxy
     97   +
             // 2) Otherwise, don't use the proxy (either the proxy isn't configured,
    +  98  
             // or proxy is specifically set to false)
    -  98  3
             final HttpURLConnection conn = URLConnectionFactory.createHttpURLConnection(url, useProxy);
    -  99   -
     
    -  100  3
             conn.setDoOutput(true);
    -  101   +  99  24
             final HttpURLConnection conn = URLConnectionFactory.createHttpURLConnection(url, useProxy);
    +  100  
     
    +  101  24
             conn.setDoOutput(true);
     102   -
             // JSON would be more elegant, but there's not currently a dependency
    +
     
     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
    -  104  3
             conn.addRequestProperty("Accept", "application/xml");
    -  105  3
             conn.connect();
    -  106   +  105  24
             conn.addRequestProperty("Accept", "application/xml");
    +  106  24
             conn.connect();
    +  107  
     
    -  107  3
             if (conn.getResponseCode() == 200) {
    -  108  3
                 boolean missing = false;
    -  109   +  108  9
             if (conn.getResponseCode() == 200) {
    +  109  9
                 boolean missing = false;
    +  110  
                 try {
    -  110  3
                     final DocumentBuilder builder = DocumentBuilderFactory
    -  111   +  111  9
                     final DocumentBuilder builder = DocumentBuilderFactory
    +  112  
                             .newInstance().newDocumentBuilder();
    -  112  3
                     final Document doc = builder.parse(conn.getInputStream());
    -  113  3
                     final XPath xpath = XPathFactory.newInstance().newXPath();
    -  114  3
                     final String numFound = xpath.evaluate("/response/result/@numFound", doc);
    -  115  3
                     if ("0".equals(numFound)) {
    -  116  1
                         missing = true;
    -  117   +  113  9
                     final Document doc = builder.parse(conn.getInputStream());
    +  114  9
                     final XPath xpath = XPathFactory.newInstance().newXPath();
    +  115  9
                     final String numFound = xpath.evaluate("/response/result/@numFound", doc);
    +  116  9
                     if ("0".equals(numFound)) {
    +  117  3
                         missing = true;
    +  118  
                     } else {
    -  118  2
                         final ArrayList<MavenArtifact> result = new ArrayList<MavenArtifact>();
    -  119  2
                         final NodeList docs = (NodeList) xpath.evaluate("/response/result/doc", doc, XPathConstants.NODESET);
    -  120  5
                         for (int i = 0; i < docs.getLength(); i++) {
    -  121  3
                             final String g = xpath.evaluate("./str[@name='g']", docs.item(i));
    -  122  3
                             LOGGER.finest(String.format("GroupId: %s", g));
    -  123  3
                             final String a = xpath.evaluate("./str[@name='a']", docs.item(i));
    -  124  3
                             LOGGER.finest(String.format("ArtifactId: %s", a));
    -  125  3
                             final String v = xpath.evaluate("./str[@name='v']", docs.item(i));
    -  126  3
                             NodeList atts = (NodeList) xpath.evaluate("./arr[@name='ec']/str", docs.item(i), XPathConstants.NODESET);
    -  127  3
                             boolean pomAvailable = false;
    -  128  3
                             boolean jarAvailable = false;
    -  129  14
                             for (int x = 0; x < atts.getLength(); x++) {
    -  130  11
                                 final String tmp = xpath.evaluate(".", atts.item(x));
    -  131  11
                                 if (".pom".equals(tmp)) {
    -  132  3
                                     pomAvailable = true;
    -  133  8
                                 } else if (".jar".equals(tmp)) {
    -  134  3
                                     jarAvailable = true;
    -  135   -
                                 }
    +  119  6
                         final ArrayList<MavenArtifact> result = new ArrayList<MavenArtifact>();
    +  120  6
                         final NodeList docs = (NodeList) xpath.evaluate("/response/result/doc", doc, XPathConstants.NODESET);
    +  121  15
                         for (int i = 0; i < docs.getLength(); i++) {
    +  122  9
                             final String g = xpath.evaluate("./str[@name='g']", docs.item(i));
    +  123  9
                             LOGGER.trace("GroupId: {}", g);
    +  124  9
                             final String a = xpath.evaluate("./str[@name='a']", docs.item(i));
    +  125  9
                             LOGGER.trace("ArtifactId: {}", a);
    +  126  9
                             final String v = xpath.evaluate("./str[@name='v']", docs.item(i));
    +  127  9
                             NodeList atts = (NodeList) xpath.evaluate("./arr[@name='ec']/str", docs.item(i), XPathConstants.NODESET);
    +  128  9
                             boolean pomAvailable = false;
    +  129  9
                             boolean jarAvailable = false;
    +  130  42
                             for (int x = 0; x < atts.getLength(); x++) {
    +  131  33
                                 final String tmp = xpath.evaluate(".", atts.item(x));
    +  132  33
                                 if (".pom".equals(tmp)) {
    +  133  9
                                     pomAvailable = true;
    +  134  24
                                 } else if (".jar".equals(tmp)) {
    +  135  9
                                     jarAvailable = true;
     136   -
                             }
    -  137   -
     
    -  138  3
                             atts = (NodeList) xpath.evaluate("./arr[@name='tags']/str", docs.item(i), XPathConstants.NODESET);
    -  139  3
                             boolean useHTTPS = false;
    -  140  21
                             for (int x = 0; x < atts.getLength(); x++) {
    -  141  18
                                 final String tmp = xpath.evaluate(".", atts.item(x));
    -  142  18
                                 if ("https".equals(tmp)) {
    -  143  0
                                     useHTTPS = true;
    -  144  
                                 }
    -  145   +  137  
                             }
    +  138   +
     
    +  139  9
                             atts = (NodeList) xpath.evaluate("./arr[@name='tags']/str", docs.item(i), XPathConstants.NODESET);
    +  140  9
                             boolean useHTTPS = false;
    +  141  63
                             for (int x = 0; x < atts.getLength(); x++) {
    +  142  54
                                 final String tmp = xpath.evaluate(".", atts.item(x));
    +  143  54
                                 if ("https".equals(tmp)) {
    +  144  0
                                     useHTTPS = true;
    +  145   +
                                 }
     146   +
                             }
    +  147  
     
    -  147  3
                             LOGGER.finest(String.format("Version: %s", v));
    -  148  3
                             result.add(new MavenArtifact(g, a, v, jarAvailable, pomAvailable, useHTTPS));
    -  149   -
                         }
    +  148  9
                             LOGGER.trace("Version: {}", v);
    +  149  9
                             result.add(new MavenArtifact(g, a, v, jarAvailable, pomAvailable, useHTTPS));
     150   +
                         }
    +  151  
     
    -  151  2
                         return result;
    -  152   +  152  6
                         return result;
    +  153  
                     }
    -  153  0
                 } catch (Throwable e) {
    -  154   -
                     // Anything else is jacked up XML stuff that we really can't recover
    +  154  0
                 } catch (Throwable e) {
     155   +
                     // Anything else is jacked up XML stuff that we really can't recover
    +  156  
                     // from well
    -  156  0
                     throw new IOException(e.getMessage(), e);
    -  157  1
                 }
    -  158   +  157  0
                     throw new IOException(e.getMessage(), e);
    +  158  3
                 }
    +  159  
     
    -  159  1
                 if (missing) {
    -  160  1
                     throw new FileNotFoundException("Artifact not found in Central");
    -  161   +  160  3
                 if (missing) {
    +  161  3
                     throw new FileNotFoundException("Artifact not found in Central");
    +  162  
                 }
    -  162  0
             } else {
    -  163  0
                 final String msg = String.format("Could not connect to Central received response code: %d %s",
    -  164   -
                         conn.getResponseCode(), conn.getResponseMessage());
    -  165  0
                 LOGGER.fine(msg);
    -  166  0
                 throw new IOException(msg);
    +  163  0
             } else {
    +  164  0
                 LOGGER.debug("Could not connect to Central received response code: {} {}",
    +  165   +
                     conn.getResponseCode(), conn.getResponseMessage());
    +  166  0
                 throw new IOException("Could not connect to Central");
     167  
             }
     168   @@ -300,6 +301,6 @@
     }
    - + 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 c789fdc07..210222dc3 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 @@ -64,55 +64,55 @@  23  
     import java.util.Set;
     24   -
     import java.util.logging.Level;
    -  25   -
     import java.util.logging.Logger;
    -  26  
     import org.apache.lucene.analysis.Analyzer;
    -  27   +  25  
     import org.apache.lucene.analysis.core.KeywordAnalyzer;
    -  28   +  26  
     import org.apache.lucene.analysis.miscellaneous.PerFieldAnalyzerWrapper;
    -  29   +  27  
     import org.apache.lucene.document.Document;
    -  30   +  28  
     import org.apache.lucene.document.Field;
    -  31   +  29  
     import org.apache.lucene.document.TextField;
    -  32   +  30  
     import org.apache.lucene.index.CorruptIndexException;
    -  33   +  31  
     import org.apache.lucene.index.DirectoryReader;
    -  34   +  32  
     import org.apache.lucene.index.IndexReader;
    -  35   +  33  
     import org.apache.lucene.index.IndexWriter;
    -  36   +  34  
     import org.apache.lucene.index.IndexWriterConfig;
    -  37   +  35  
     import org.apache.lucene.queryparser.classic.ParseException;
    -  38   +  36  
     import org.apache.lucene.queryparser.classic.QueryParser;
    -  39   +  37  
     import org.apache.lucene.search.IndexSearcher;
    -  40   +  38  
     import org.apache.lucene.search.Query;
    -  41   +  39  
     import org.apache.lucene.search.TopDocs;
    -  42   +  40  
     import org.apache.lucene.store.RAMDirectory;
    -  43   +  41  
     import org.owasp.dependencycheck.data.lucene.FieldAnalyzer;
    -  44   +  42  
     import org.owasp.dependencycheck.data.lucene.LuceneUtils;
    -  45   +  43  
     import org.owasp.dependencycheck.data.lucene.SearchFieldAnalyzer;
    -  46   +  44  
     import org.owasp.dependencycheck.data.nvdcve.CveDB;
    -  47   +  45  
     import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
    -  48   +  46  
     import org.owasp.dependencycheck.utils.Pair;
    +  47   +
     import org.slf4j.Logger;
    +  48   +
     import org.slf4j.LoggerFactory;
     49  
     
     50   @@ -137,14 +137,14 @@
          * The logger.
     60  
          */
    -  61  1
         private static final Logger LOGGER = Logger.getLogger(CpeMemoryIndex.class.getName());
    +  61  8
         private static final Logger LOGGER = LoggerFactory.getLogger(CpeMemoryIndex.class);
     62  
         /**
     63  
          * singleton instance.
     64  
          */
    -  65  1
         private static final CpeMemoryIndex INSTANCE = new CpeMemoryIndex();
    +  65  8
         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  8
         private CpeMemoryIndex() {
    +  71  8
         }
     72  
     
     73   @@ -169,7 +169,7 @@
          */
     78  
         public static CpeMemoryIndex getInstance() {
    -  79  1
             return INSTANCE;
    +  79  8
             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  8
             synchronized (INSTANCE) {
    +  118  8
                 if (!openState) {
    +  119  8
                     index = new RAMDirectory();
    +  120  8
                     buildIndex(cve);
     121  
                     try {
    -  122  1
                         indexReader = DirectoryReader.open(index);
    +  122  8
                         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  8
                     }
    +  126  8
                     indexSearcher = new IndexSearcher(indexReader);
    +  127  8
                     searchingAnalyzer = createSearchingAnalyzer();
    +  128  8
                     queryParser = new QueryParser(LuceneUtils.CURRENT_VERSION, Fields.DOCUMENT_KEY, searchingAnalyzer);
    +  129  8
                     openState = true;
     130  
                 }
    -  131  1
             }
    -  132  1
         }
    +  131  8
             }
    +  132  8
         }
     133  
         /**
     134  
          * A flag indicating whether or not the index is open.
     135  
          */
    -  136  1
         private boolean openState = false;
    +  136  8
         private boolean openState = false;
     137  
     
     138   @@ -302,9 +302,9 @@
         @SuppressWarnings("unchecked")
     153  
         private Analyzer createIndexingAnalyzer() {
    -  154  1
             final Map fieldAnalyzers = new HashMap();
    -  155  1
             fieldAnalyzers.put(Fields.DOCUMENT_KEY, new KeywordAnalyzer());
    -  156  1
             return new PerFieldAnalyzerWrapper(new FieldAnalyzer(LuceneUtils.CURRENT_VERSION), fieldAnalyzers);
    +  154  8
             final Map fieldAnalyzers = new HashMap();
    +  155  8
             fieldAnalyzers.put(Fields.DOCUMENT_KEY, new KeywordAnalyzer());
    +  156  8
             return new PerFieldAnalyzerWrapper(new FieldAnalyzer(LuceneUtils.CURRENT_VERSION), fieldAnalyzers);
     157  
         }
     158   @@ -323,15 +323,15 @@
         @SuppressWarnings("unchecked")
     165  
         private Analyzer createSearchingAnalyzer() {
    -  166  1
             final Map<String, Analyzer> fieldAnalyzers = new HashMap<String, Analyzer>();
    -  167  1
             fieldAnalyzers.put(Fields.DOCUMENT_KEY, new KeywordAnalyzer());
    -  168  1
             productSearchFieldAnalyzer = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION);
    -  169  1
             vendorSearchFieldAnalyzer = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION);
    -  170  1
             fieldAnalyzers.put(Fields.PRODUCT, productSearchFieldAnalyzer);
    -  171  1
             fieldAnalyzers.put(Fields.VENDOR, vendorSearchFieldAnalyzer);
    +  166  8
             final Map<String, Analyzer> fieldAnalyzers = new HashMap<String, Analyzer>();
    +  167  8
             fieldAnalyzers.put(Fields.DOCUMENT_KEY, new KeywordAnalyzer());
    +  168  8
             productSearchFieldAnalyzer = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION);
    +  169  8
             vendorSearchFieldAnalyzer = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION);
    +  170  8
             fieldAnalyzers.put(Fields.PRODUCT, productSearchFieldAnalyzer);
    +  171  8
             fieldAnalyzers.put(Fields.VENDOR, vendorSearchFieldAnalyzer);
     172  
     
    -  173  1
             return new PerFieldAnalyzerWrapper(new FieldAnalyzer(LuceneUtils.CURRENT_VERSION), fieldAnalyzers);
    +  173  8
             return new PerFieldAnalyzerWrapper(new FieldAnalyzer(LuceneUtils.CURRENT_VERSION), fieldAnalyzers);
     174  
         }
     175   @@ -356,13 +356,13 @@
          */
     185  
         public void saveEntry(String vendor, String product, IndexWriter indexWriter) throws CorruptIndexException, IOException {
    -  186  24879
             final Document doc = new Document();
    -  187  24879
             final Field v = new TextField(Fields.VENDOR, vendor, Field.Store.YES);
    -  188  24879
             final Field p = new TextField(Fields.PRODUCT, product, Field.Store.YES);
    -  189  24879
             doc.add(v);
    -  190  24879
             doc.add(p);
    -  191  24879
             indexWriter.addDocument(doc);
    -  192  24879
         }
    +  186  201178
             final Document doc = new Document();
    +  187  201178
             final Field v = new TextField(Fields.VENDOR, vendor, Field.Store.YES);
    +  188  201178
             final Field p = new TextField(Fields.PRODUCT, product, Field.Store.YES);
    +  189  201178
             doc.add(v);
    +  190  201178
             doc.add(p);
    +  191  201178
             indexWriter.addDocument(doc);
    +  192  201178
         }
     193  
     
     194   @@ -373,30 +373,30 @@
          */
     197  
         public void close() {
    -  198  1
             if (searchingAnalyzer != null) {
    -  199  1
                 searchingAnalyzer.close();
    -  200  1
                 searchingAnalyzer = null;
    +  198  8
             if (searchingAnalyzer != null) {
    +  199  8
                 searchingAnalyzer.close();
    +  200  8
                 searchingAnalyzer = null;
     201  
             }
    -  202  1
             if (indexReader != null) {
    +  202  8
             if (indexReader != null) {
     203  
                 try {
    -  204  1
                     indexReader.close();
    +  204  8
                     indexReader.close();
     205  0
                 } catch (IOException ex) {
    -  206  0
                     LOGGER.log(Level.FINEST, null, ex);
    -  207  1
                 }
    -  208  1
                 indexReader = null;
    +  206  0
                     LOGGER.trace("", ex);
    +  207  8
                 }
    +  208  8
                 indexReader = null;
     209  
             }
    -  210  1
             queryParser = null;
    -  211  1
             indexSearcher = null;
    -  212  1
             if (index != null) {
    -  213  1
                 index.close();
    -  214  1
                 index = null;
    +  210  8
             queryParser = null;
    +  211  8
             indexSearcher = null;
    +  212  8
             if (index != null) {
    +  213  8
                 index.close();
    +  214  8
                 index = null;
     215  
             }
    -  216  1
             openState = false;
    -  217  1
         }
    +  216  8
             openState = false;
    +  217  8
         }
     218  
     
     219   @@ -413,53 +413,53 @@
          */
     225  
         private void buildIndex(CveDB cve) throws IndexException {
    -  226  1
             Analyzer analyzer = null;
    -  227  1
             IndexWriter indexWriter = null;
    +  226  8
             Analyzer analyzer = null;
    +  227  8
             IndexWriter indexWriter = null;
     228  
             try {
    -  229  1
                 analyzer = createIndexingAnalyzer();
    -  230  1
                 final IndexWriterConfig conf = new IndexWriterConfig(LuceneUtils.CURRENT_VERSION, analyzer);
    -  231  1
                 indexWriter = new IndexWriter(index, conf);
    +  229  8
                 analyzer = createIndexingAnalyzer();
    +  230  8
                 final IndexWriterConfig conf = new IndexWriterConfig(LuceneUtils.CURRENT_VERSION, analyzer);
    +  231  8
                 indexWriter = new IndexWriter(index, conf);
     232  
                 try {
    -  233  1
                     final Set<Pair<String, String>> data = cve.getVendorProductList();
    -  234  1
                     for (Pair<String, String> pair : data) {
    -  235  24879
                         saveEntry(pair.getLeft(), pair.getRight(), indexWriter);
    -  236  24879
                     }
    +  233  8
                     final Set<Pair<String, String>> data = cve.getVendorProductList();
    +  234  8
                     for (Pair<String, String> pair : data) {
    +  235  201178
                         saveEntry(pair.getLeft(), pair.getRight(), indexWriter);
    +  236  201178
                     }
     237  0
                 } catch (DatabaseException ex) {
    -  238  0
                     LOGGER.log(Level.FINE, null, ex);
    +  238  0
                     LOGGER.debug("", ex);
     239  0
                     throw new IndexException("Error reading CPE data", ex);
    -  240  1
                 }
    +  240  8
                 }
     241  0
             } catch (CorruptIndexException ex) {
     242  0
                 throw new IndexException("Unable to close an in-memory index", ex);
     243  0
             } catch (IOException ex) {
     244  0
                 throw new IndexException("Unable to close an in-memory index", ex);
     245  
             } finally {
    -  246  1
                 if (indexWriter != null) {
    +  246  8
                 if (indexWriter != null) {
     247  
                     try {
     248  
                         try {
    -  249  1
                             indexWriter.commit();
    +  249  8
                             indexWriter.commit();
     250  
                         } finally {
    -  251  1
                             indexWriter.close(true);
    -  252  1
                         }
    +  251  8
                             indexWriter.close(true);
    +  252  8
                         }
     253  0
                     } catch (CorruptIndexException ex) {
     254  0
                         throw new IndexException("Unable to close an in-memory index", ex);
     255  0
                     } catch (IOException ex) {
     256  0
                         throw new IndexException("Unable to close an in-memory index", ex);
    -  257  1
                     }
    -  258  1
                     if (analyzer != null) {
    -  259  1
                         analyzer.close();
    +  257  8
                     }
    +  258  8
                     if (analyzer != null) {
    +  259  8
                         analyzer.close();
     260  
                     }
     261  
                 }
     262  
             }
    -  263  1
         }
    +  263  8
         }
     264  
     
     265   @@ -501,12 +501,12 @@
          */
     286  
         public TopDocs search(String searchString, int maxQueryResults) throws ParseException, IOException {
    -  287  6
             if (searchString == null || searchString.trim().isEmpty()) {
    +  287  48
             if (searchString == null || searchString.trim().isEmpty()) {
     288  0
                 throw new ParseException("Query is null or empty");
     289  
             }
    -  290  6
             final Query query = queryParser.parse(searchString);
    -  291  6
             return indexSearcher.search(query, maxQueryResults);
    +  290  48
             final Query query = queryParser.parse(searchString);
    +  291  48
             return indexSearcher.search(query, maxQueryResults);
     292  
         }
     293   @@ -553,7 +553,7 @@
          */
     315  
         public Document getDocument(int documentId) throws IOException {
    -  316  47
             return indexSearcher.doc(documentId);
    +  316  344
             return indexSearcher.doc(documentId);
     317  
         }
     318   @@ -581,6 +581,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 11829693e..05852edb4 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 e3535891d..9e5159a7e 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 @@ -12,7 +12,7 @@
     
    - +
    Classes in this File Line Coverage Branch Coverage Complexity
    IndexEntry
    66%
    24/36
    34%
    11/32
    2.5
    IndexEntry
    63%
    23/36
    34%
    11/32
    2.5
     
    @@ -73,7 +73,7 @@
      * @author Jeremy Long
     28  
      */
    -  29  1381
     public class IndexEntry implements Serializable {
    +  29  12192
     public class IndexEntry implements Serializable {
     30  
     
     31   @@ -151,7 +151,7 @@
          */
     70  
         public String getVendor() {
    -  71  19
             return vendor;
    +  71  240
             return vendor;
     72  
         }
     73   @@ -168,8 +168,8 @@
          */
     79  
         public void setVendor(String vendor) {
    -  80  1380
             this.vendor = vendor;
    -  81  1380
         }
    +  80  12184
             this.vendor = vendor;
    +  81  12184
         }
     82  
         /**
     83   @@ -192,7 +192,7 @@
          */
     92  
         public String getProduct() {
    -  93  62
             return product;
    +  93  504
             return product;
     94  
         }
     95   @@ -209,8 +209,8 @@
          */
     101  
         public void setProduct(String product) {
    -  102  1380
             this.product = product;
    -  103  1380
         }
    +  102  12184
             this.product = product;
    +  103  12184
         }
     104  
         /**
     105   @@ -250,8 +250,8 @@
          */
     123  
         public void setSearchScore(float searchScore) {
    -  124  47
             this.searchScore = searchScore;
    -  125  47
         }
    +  124  344
             this.searchScore = searchScore;
    +  125  344
         }
     126  
     
     127   @@ -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  8
             if (cpeName != null && cpeName.length() > 7) {
    +  146  8
                 final String[] data = cpeName.substring(7).split(":");
    +  147  8
                 if (data.length >= 1) {
    +  148  8
                     vendor = URLDecoder.decode(data[0].replace("+", "%2B"), "UTF-8");
    +  149  8
                     if (data.length >= 2) {
    +  150  8
                         product = URLDecoder.decode(data[1].replace("+", "%2B"), "UTF-8");
     151  
                     }
     152  
                 }
     153  
             }
    -  154  1
         }
    +  154  8
         }
     155  
     
     156   @@ -320,21 +320,21 @@
         @Override
     164  
         public boolean equals(Object obj) {
    -  165  171
             if (obj == null) {
    +  165  1224
             if (obj == null) {
     166  0
                 return false;
     167  
             }
    -  168  171
             if (getClass() != obj.getClass()) {
    +  168  1224
             if (getClass() != obj.getClass()) {
     169  0
                 return false;
     170  
             }
    -  171  171
             final IndexEntry other = (IndexEntry) obj;
    -  172  171
             if ((this.vendor == null) ? (other.vendor != null) : !this.vendor.equals(other.vendor)) {
    -  173  166
                 return false;
    +  171  1224
             final IndexEntry other = (IndexEntry) obj;
    +  172  1224
             if ((this.vendor == null) ? (other.vendor != null) : !this.vendor.equals(other.vendor)) {
    +  173  1184
                 return false;
     174  
             }
    -  175  5
             if ((this.product == null) ? (other.product != null) : !this.product.equals(other.product)) {
    -  176  5
                 return false;
    +  175  40
             if ((this.product == null) ? (other.product != null) : !this.product.equals(other.product)) {
    +  176  40
                 return false;
     177  
             }
     178  0
             return true;
    @@ -356,13 +356,13 @@
         @Override
     187  
         public String toString() {
    -  188  47
             return "IndexEntry{" + "vendor=" + vendor + ", product=" + product + '}';
    +  188  0
             return "IndexEntry{" + "vendor=" + vendor + ", product=" + product + '}';
     189  
         }
     190  
     }
    - + 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 5db591b46..821fea1d6 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 d0db49fe9..b8d821a79 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 @@ -56,132 +56,134 @@  19  
     
     20   -
     import java.io.IOException;
    +
     import org.slf4j.Logger;
     21   -
     import java.io.InputStream;
    +
     import org.slf4j.LoggerFactory;
     22   -
     import java.io.ObjectInputStream;
    +
     
     23   -
     import java.util.HashMap;
    +
     import java.io.IOException;
     24   -
     import java.util.logging.Level;
    +
     import java.io.InputStream;
     25   -
     import java.util.logging.Logger;
    +
     import java.io.ObjectInputStream;
     26   -
     
    +
     import java.util.HashMap;
     27   -
     /**
    +
     
     28   -
      *
    +
     /**
     29   -
      * @author Jeremy Long
    +
      *
     30   -
      */
    +
      * @author Jeremy Long
     31   -
     public final class CweDB {
    +
      */
     32   -
     
    +
     public final class CweDB {
     33   -
         /**
    +
     
     34   -
          * The Logger.
    +
         /**
     35   +
          * The Logger.
    +  36  
          */
    -  36  1
         private static final Logger LOGGER = Logger.getLogger(CweDB.class.getName());
    -  37   -
     
    +  37  8
         private static final Logger LOGGER = LoggerFactory.getLogger(CweDB.class);
     38   -
         /**
    +
     
     39   -
          * Empty private constructor as this is a utility class.
    +
         /**
     40   +
          * Empty private constructor as this is a utility class.
    +  41  
          */
    -  41  0
         private CweDB() {
    -  42   +  42  0
         private CweDB() {
    +  43  
             //empty
    -  43  0
         }
    -  44   -
         /**
    +  44  0
         }
     45   -
          * A HashMap of the CWE data.
    +
         /**
     46   +
          * A HashMap of the CWE data.
    +  47  
          */
    -  47  1
         private static final HashMap<String, String> CWE = loadData();
    -  48   -
     
    +  48  8
         private static final HashMap<String, String> CWE = loadData();
     49   -
         /**
    -  50   -
          * Loads a HashMap containing the CWE data from a resource found in the jar.
    -  51   -
          *
    -  52   -
          * @return a HashMap of CWE data
    -  53   -
          */
    -  54   -
         private static HashMap<String, String> loadData() {
    -  55  1
             ObjectInputStream oin = null;
    -  56   -
             try {
    -  57  1
                 final String filePath = "data/cwe.hashmap.serialized";
    -  58  1
                 final InputStream input = CweDB.class.getClassLoader().getResourceAsStream(filePath);
    -  59  1
                 oin = new ObjectInputStream(input);
    -  60   -
                 @SuppressWarnings("unchecked")
    -  61  1
                 final HashMap<String, String> ret = (HashMap<String, String>) oin.readObject();
    -  62  1
                 return ret;
    -  63  0
             } catch (ClassNotFoundException ex) {
    -  64  0
                 LOGGER.log(Level.WARNING, "Unable to load CWE data. This should not be an issue.");
    -  65  0
                 LOGGER.log(Level.FINE, null, ex);
    -  66  0
             } catch (IOException ex) {
    -  67  0
                 LOGGER.log(Level.WARNING, "Unable to load CWE data due to an IO Error. This should not be an issue.");
    -  68  0
                 LOGGER.log(Level.FINE, null, ex);
    -  69   -
             } finally {
    -  70  1
                 if (oin != null) {
    -  71   -
                     try {
    -  72  1
                         oin.close();
    -  73  0
                     } catch (IOException ex) {
    -  74  0
                         LOGGER.log(Level.FINEST, null, ex);
    -  75  2
                     }
    -  76   -
                 }
    -  77   -
             }
    -  78  0
             return null;
    -  79   -
         }
    -  80  
     
    -  81   +  50  
         /**
    -  82   -
          * <p>
    -  83   -
          * Returns the full CWE name from the CWE ID.</p>
    -  84   +  51   +
          * Loads a HashMap containing the CWE data from a resource found in the jar.
    +  52  
          *
    -  85   -
          * @param cweId the CWE ID
    -  86   -
          * @return the full name of the CWE
    -  87   +  53   +
          * @return a HashMap of CWE data
    +  54  
          */
    -  88   -
         public static String getCweName(String cweId) {
    -  89  9
             if (cweId != null) {
    -  90  9
                 return CWE.get(cweId);
    -  91   +  55   +
         private static HashMap<String, String> loadData() {
    +  56  8
             ObjectInputStream oin = null;
    +  57   +
             try {
    +  58  8
                 final String filePath = "data/cwe.hashmap.serialized";
    +  59  8
                 final InputStream input = CweDB.class.getClassLoader().getResourceAsStream(filePath);
    +  60  8
                 oin = new ObjectInputStream(input);
    +  61   +
                 @SuppressWarnings("unchecked")
    +  62  8
                 final HashMap<String, String> ret = (HashMap<String, String>) oin.readObject();
    +  63  8
                 return ret;
    +  64  0
             } catch (ClassNotFoundException ex) {
    +  65  0
                 LOGGER.warn("Unable to load CWE data. This should not be an issue.");
    +  66  0
                 LOGGER.debug("", ex);
    +  67  0
             } catch (IOException ex) {
    +  68  0
                 LOGGER.warn("Unable to load CWE data due to an IO Error. This should not be an issue.");
    +  69  0
                 LOGGER.debug("", ex);
    +  70   +
             } finally {
    +  71  8
                 if (oin != null) {
    +  72   +
                     try {
    +  73  8
                         oin.close();
    +  74  0
                     } catch (IOException ex) {
    +  75  0
                         LOGGER.trace("", ex);
    +  76  16
                     }
    +  77   +
                 }
    +  78  
             }
    -  92  0
             return null;
    -  93   +  79  0
             return null;
    +  80  
         }
    +  81   +
     
    +  82   +
         /**
    +  83   +
          * <p>
    +  84   +
          * Returns the full CWE name from the CWE ID.</p>
    +  85   +
          *
    +  86   +
          * @param cweId the CWE ID
    +  87   +
          * @return the full name of the CWE
    +  88   +
          */
    +  89   +
         public static String getCweName(String cweId) {
    +  90  72
             if (cweId != null) {
    +  91  72
                 return CWE.get(cweId);
    +  92   +
             }
    +  93  0
             return null;
     94   +
         }
    +  95  
     }
    - + 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 f73720a0b..3eb9208eb 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 d095ddaab..6e91b2cf0 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  83
         private final CharTermAttribute termAtt = addAttribute(CharTermAttribute.class);
     36  
     
     37   @@ -100,7 +100,7 @@
          */
     42  
         protected CharTermAttribute getTermAtt() {
    -  43  31895
             return termAtt;
    +  43  224495
             return termAtt;
     44  
         }
     45   @@ -125,7 +125,7 @@
          */
     55  
         protected LinkedList<String> getTokens() {
    -  56  31867
             return tokens;
    +  56  224288
             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  83
             super(stream);
    +  66  83
             tokens = new LinkedList<String>();
    +  67  83
         }
     68  
     
     69   @@ -159,20 +159,20 @@
          */
     74  
         protected boolean addTerm() {
    -  75  31812
             final boolean termAdded = !tokens.isEmpty();
    -  76  31818
             if (termAdded) {
    -  77  21233
                 final String term = tokens.pop();
    -  78  21211
                 clearAttributes();
    -  79  21217
                 termAtt.append(term);
    +  75  223708
             final boolean termAdded = !tokens.isEmpty();
    +  76  223691
             if (termAdded) {
    +  77  149115
                 final String term = tokens.pop();
    +  78  149045
                 clearAttributes();
    +  79  149103
                 termAtt.append(term);
     80  
             }
    -  81  31807
             return termAdded;
    +  81  223641
             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 58b8d2825..0e6b4ff83 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  56
             super(matchVersion, in);
    +  39  56
         }
     40  
     
     41   @@ -131,13 +131,13 @@
         @Override
     59  
         protected boolean isTokenChar(int c) {
    -  60  594106
             return Character.isLetter(c) || Character.isDigit(c);
    +  60  4812152
             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 f465013c8..3a27ad301 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 e79120e7a..d3a1ccbd2 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  24
         public FieldAnalyzer(Version version) {
    +  50  24
             this.version = version;
    +  51  24
         }
     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  24
             final Tokenizer source = new AlphaNumericTokenizer(version, reader);
     63  
     
    -  64  3
             TokenStream stream = source;
    +  64  24
             TokenStream stream = source;
     65  
     
    -  66  3
             stream = new WordDelimiterFilter(stream,
    +  66  24
             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  24
             stream = new LowerCaseFilter(version, stream);
    +  76  24
             stream = new StopFilter(version, stream, StopAnalyzer.ENGLISH_STOP_WORDS_SET);
     77  
     
    -  78  3
             return new TokenStreamComponents(source, stream);
    +  78  24
             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 2777e7d3f..b61eed8fa 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  8
         public static final Version CURRENT_VERSION = Version.LUCENE_47;
     36  
     
     37   @@ -124,15 +124,15 @@
                 final CharSequence text) {
     55  
     
    -  56  150
             if (text == null || buf == null) {
    -  57  1
                 return;
    +  56  1160
             if (text == null || buf == null) {
    +  57  8
                 return;
     58  
             }
     59  
     
    -  60  1291
             for (int i = 0; i < text.length(); i++) {
    -  61  1142
                 final char c = text.charAt(i);
    -  62  1142
                 switch (c) {
    +  60  10104
             for (int i = 0; i < text.length(); i++) {
    +  61  8952
                 final char c = text.charAt(i);
    +  62  8952
                 switch (c) {
     63  
                     case '+':
     64   @@ -169,17 +169,17 @@
                     case ':':
     80  
                     case '\\': //it is supposed to fall through here
    -  81  58
                         buf.append('\\');
    +  81  464
                         buf.append('\\');
     82  
                     default:
    -  83  1142
                         buf.append(c);
    +  83  8952
                         buf.append(c);
     84  
                         break;
     85  
                 }
     86  
             }
    -  87  149
         }
    +  87  1152
         }
     88  
     
     89   @@ -198,27 +198,27 @@
         public static String escapeLuceneQuery(final CharSequence text) {
     96  
     
    -  97  149
             if (text == null) {
    -  98  1
                 return null;
    +  97  1152
             if (text == null) {
    +  98  8
                 return null;
     99  
             }
     100  
     
    -  101  148
             int size = text.length();
    -  102  148
             size = size >> 1;
    -  103  148
             final StringBuilder buf = new StringBuilder(size);
    +  101  1144
             int size = text.length();
    +  102  1144
             size = size >> 1;
    +  103  1144
             final StringBuilder buf = new StringBuilder(size);
     104  
     
    -  105  148
             appendEscapedLuceneQuery(buf, text);
    +  105  1144
             appendEscapedLuceneQuery(buf, text);
     106  
     
    -  107  148
             return buf.toString();
    +  107  1144
             return buf.toString();
     108  
         }
     109  
     }
    - + 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 8aea8efcc..d12162a1c 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  32
         public SearchFieldAnalyzer(Version version) {
    +  52  32
             this.version = version;
    +  53  32
         }
     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  32
             final Tokenizer source = new AlphaNumericTokenizer(version, reader);
     65  
     
    -  66  4
             TokenStream stream = source;
    +  66  32
             TokenStream stream = source;
     67  
     
    -  68  4
             stream = new WordDelimiterFilter(stream,
    +  68  32
             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  32
             stream = new LowerCaseFilter(version, stream);
    +  77  32
             stream = new UrlTokenizingFilter(stream);
    +  78  32
             concatenatingFilter = new TokenPairConcatenatingFilter(stream);
    +  79  32
             stream = concatenatingFilter;
    +  80  32
             stream = new StopFilter(version, stream, StopAnalyzer.ENGLISH_STOP_WORDS_SET);
     81  
     
    -  82  4
             return new TokenStreamComponents(source, stream);
    +  82  32
             return new TokenStreamComponents(source, stream);
     83  
         }
     84   @@ -187,15 +187,15 @@
          */
     91  
         public void clear() {
    -  92  2
             if (concatenatingFilter != null) {
    -  93  2
                 concatenatingFilter.clear();
    +  92  16
             if (concatenatingFilter != null) {
    +  93  16
                 concatenatingFilter.clear();
     94  
             }
    -  95  2
         }
    +  95  16
         }
     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 1ca9cde08..30af2a422 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  48
         private final CharTermAttribute termAtt = addAttribute(CharTermAttribute.class);
     40  
         /**
     41   @@ -124,7 +124,7 @@
          */
     54  
         protected String getPreviousWord() {
    -  55  2
             return previousWord;
    +  55  16
             return previousWord;
     56  
         }
     57   @@ -141,7 +141,7 @@
          */
     63  
         protected LinkedList<String> getWords() {
    -  64  1
             return words;
    +  64  8
             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  48
             super(stream);
    +  74  48
             words = new LinkedList<String>();
    +  75  48
         }
     76  
     
     77   @@ -185,35 +185,35 @@
     
     87  
             //collect all the terms into the words collection
    -  88  842
             while (input.incrementToken()) {
    -  89  232
                 final String word = new String(termAtt.buffer(), 0, termAtt.length());
    -  90  232
                 words.add(word);
    -  91  232
             }
    +  88  6576
             while (input.incrementToken()) {
    +  89  1816
                 final String word = new String(termAtt.buffer(), 0, termAtt.length());
    +  90  1816
                 words.add(word);
    +  91  1816
             }
     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  610
             if (previousWord != null && !words.isEmpty()) {
    -  96  224
                 final String word = words.getFirst();
    -  97  224
                 clearAttributes();
    -  98  224
                 termAtt.append(previousWord).append(word);
    -  99  224
                 previousWord = null;
    -  100  224
                 return true;
    +  95  4760
             if (previousWord != null && !words.isEmpty()) {
    +  96  1752
                 final String word = words.getFirst();
    +  97  1752
                 clearAttributes();
    +  98  1752
                 termAtt.append(previousWord).append(word);
    +  99  1752
                 previousWord = null;
    +  100  1752
                 return true;
     101  
             }
     102  
             //if we have words, write it out as a single token
    -  103  386
             if (!words.isEmpty()) {
    -  104  232
                 final String word = words.removeFirst();
    -  105  232
                 clearAttributes();
    -  106  232
                 termAtt.append(word);
    -  107  232
                 previousWord = word;
    -  108  232
                 return true;
    +  103  3008
             if (!words.isEmpty()) {
    +  104  1816
                 final String word = words.removeFirst();
    +  105  1816
                 clearAttributes();
    +  106  1816
                 termAtt.append(word);
    +  107  1816
                 previousWord = word;
    +  108  1816
                 return true;
     109  
             }
    -  110  154
             return false;
    +  110  1192
             return false;
     111  
         }
     112   @@ -234,13 +234,13 @@
          */
     120  
         public void clear() {
    -  121  3
             previousWord = null;
    -  122  3
             words.clear();
    -  123  3
         }
    +  121  24
             previousWord = null;
    +  122  24
             words.clear();
    +  123  24
         }
     124  
     }
    - + 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 2c8fe6bf6..533d71f37 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 @@ -64,15 +64,15 @@  23  
     import java.util.List;
     24   -
     import java.util.logging.Level;
    -  25   -
     import java.util.logging.Logger;
    -  26  
     import org.apache.lucene.analysis.TokenStream;
    -  27   +  25  
     import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
    -  28   +  26  
     import org.owasp.dependencycheck.utils.UrlStringUtils;
    +  27   +
     import org.slf4j.Logger;
    +  28   +
     import org.slf4j.LoggerFactory;
     29  
     
     30   @@ -99,7 +99,7 @@
          * The logger.
     41  
          */
    -  42  1
         private static final Logger LOGGER = Logger.getLogger(UrlTokenizingFilter.class.getName());
    +  42  8
         private static final Logger LOGGER = LoggerFactory.getLogger(UrlTokenizingFilter.class);
     43  
         /**
     44   @@ -112,8 +112,8 @@
          */
     48  
         public UrlTokenizingFilter(TokenStream stream) {
    -  49  11
             super(stream);
    -  50  11
         }
    +  49  83
             super(stream);
    +  50  83
         }
     51  
     
     52   @@ -134,22 +134,22 @@
         @Override
     60  
         public boolean incrementToken() throws IOException {
    -  61  31804
             final LinkedList<String> tokens = getTokens();
    -  62  31860
             final CharTermAttribute termAtt = getTermAtt();
    -  63  31889
             if (tokens.isEmpty() && input.incrementToken()) {
    -  64  21247
                 final String text = new String(termAtt.buffer(), 0, termAtt.length());
    -  65  21232
                 if (UrlStringUtils.containsUrl(text)) {
    -  66  6
                     final String[] parts = text.split("\\s");
    -  67  12
                     for (String part : parts) {
    -  68  6
                         if (UrlStringUtils.isUrl(part)) {
    +  61  223990
             final LinkedList<String> tokens = getTokens();
    +  62  224217
             final CharTermAttribute termAtt = getTermAtt();
    +  63  224401
             if (tokens.isEmpty() && input.incrementToken()) {
    +  64  149295
                 final String text = new String(termAtt.buffer(), 0, termAtt.length());
    +  65  149249
                 if (UrlStringUtils.containsUrl(text)) {
    +  66  48
                     final String[] parts = text.split("\\s");
    +  67  96
                     for (String part : parts) {
    +  68  48
                         if (UrlStringUtils.isUrl(part)) {
     69  
                             try {
    -  70  6
                                 final List<String> data = UrlStringUtils.extractImportantUrlData(part);
    -  71  6
                                 tokens.addAll(data);
    +  70  48
                                 final List<String> data = UrlStringUtils.extractImportantUrlData(part);
    +  71  48
                                 tokens.addAll(data);
     72  0
                             } catch (MalformedURLException ex) {
    -  73  0
                                 LOGGER.log(Level.FINE, "error parsing " + part, ex);
    +  73  0
                                 LOGGER.debug("error parsing {}", part, ex);
     74  0
                                 tokens.add(part);
    -  75  6
                             }
    +  75  48
                             }
     76  
                         } else {
     77  0
                             tokens.add(part);
    @@ -157,19 +157,19 @@
                         }
     79  
                     }
    -  80  6
                 } else {
    -  81  21236
                     tokens.add(text);
    +  80  48
                 } else {
    +  81  149203
                     tokens.add(text);
     82  
                 }
     83  
             }
    -  84  31803
             return addTerm();
    +  84  223725
             return addTerm();
     85  
         }
     86  
     }
    - + 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 05754a839..2234b6b53 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  9
         public MavenArtifact(String groupId, String artifactId, String version, boolean jarAvailable, boolean pomAvailable, boolean secureDownload) {
    +  86  9
             this.groupId = groupId;
    +  87  9
             this.artifactId = artifactId;
    +  88  9
             this.version = version;
     89  
             String base;
    -  90  3
             if (secureDownload) {
    +  90  9
             if (secureDownload) {
     91  0
                 base = "https:" + CENTRAL_CONTENT_URL;
     92  
             } else {
    -  93  3
                 base = "http:" + CENTRAL_CONTENT_URL;
    +  93  9
                 base = "http:" + CENTRAL_CONTENT_URL;
     94  
             }
    -  95  3
             if (jarAvailable) {
    +  95  9
             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  9
                 this.artifactUrl = base + groupId.replace('.', '/') + "/" + artifactId + "/"
     98  
                         + version + "/" + artifactId + "-" + version + ".jar";
     99  
             }
    -  100  3
             if (pomAvailable) {
    +  100  9
             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  9
                 this.pomUrl = base + groupId.replace('.', '/') + "/" + artifactId + "/"
     103  
                         + version + "/" + artifactId + "-" + version + ".pom";
     104  
             }
    -  105  3
         }
    +  105  9
         }
     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  16
         public MavenArtifact(String groupId, String artifactId, String version, String url) {
    +  116  16
             this.groupId = groupId;
    +  117  16
             this.artifactId = artifactId;
    +  118  16
             this.version = version;
    +  119  16
             this.artifactUrl = url;
    +  120  16
         }
     121  
     
     122   @@ -248,7 +248,7 @@
         @Override
     128  
         public String toString() {
    -  129  2
             return String.format("%s:%s:%s", groupId, artifactId, version);
    +  129  16
             return String.format("%s:%s:%s", groupId, artifactId, version);
     130  
         }
     131   @@ -281,7 +281,7 @@
          */
     146  
         public String getGroupId() {
    -  147  5
             return groupId;
    +  147  35
             return groupId;
     148  
         }
     149   @@ -314,7 +314,7 @@
          */
     164  
         public String getArtifactId() {
    -  165  5
             return artifactId;
    +  165  35
             return artifactId;
     166  
         }
     167   @@ -347,7 +347,7 @@
          */
     182  
         public String getVersion() {
    -  183  5
             return version;
    +  183  35
             return version;
     184  
         }
     185   @@ -380,7 +380,7 @@
          */
     200  
         public String getArtifactUrl() {
    -  201  4
             return artifactUrl;
    +  201  32
             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 1ff7aa9eb..ab4609b95 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 @@ -12,7 +12,7 @@
     
    - +
    Classes in this File Line Coverage Branch Coverage Complexity
    NexusSearch
    0%
    0/59
    0%
    0/24
    8.667
    NexusSearch
    0%
    0/57
    0%
    0/24
    8.667
     
    @@ -64,23 +64,23 @@  23  
     import java.net.URL;
     24   -
     import java.util.logging.Level;
    -  25   -
     import java.util.logging.Logger;
    -  26  
     import javax.xml.parsers.DocumentBuilder;
    -  27   +  25  
     import javax.xml.parsers.DocumentBuilderFactory;
    -  28   +  26  
     import javax.xml.xpath.XPath;
    -  29   +  27  
     import javax.xml.xpath.XPathFactory;
    -  30   +  28  
     import org.owasp.dependencycheck.utils.InvalidSettingException;
    -  31   +  29  
     import org.owasp.dependencycheck.utils.Settings;
    -  32   +  30  
     import org.owasp.dependencycheck.utils.URLConnectionFactory;
    +  31   +
     import org.slf4j.Logger;
    +  32   +
     import org.slf4j.LoggerFactory;
     33  
     import org.w3c.dom.Document;
     34   @@ -120,236 +120,220 @@  51  
         /**
     52   -
          * The username to use if the Nexus requires authentication.
    +
          * Used for logging.
     53  
          */
    -  54  0
         private String userName = null;
    +  54  0
         private static final Logger LOGGER = LoggerFactory.getLogger(NexusSearch.class);
     55   -
         /**
    +
     
     56   -
          * The password to use if the Nexus requires authentication.
    -  57   -
          */
    -  58   -
         private char[] password;
    -  59  
         /**
    +  57   +
          * Creates a NexusSearch for the given repository URL.
    +  58   +
          *
    +  59   +
          * @param rootURL the root URL of the repository on which searches should execute. full URL's are calculated relative to this
     60   -
          * Used for logging.
    +
          * URL, so it should end with a /
     61  
          */
    -  62  0
         private static final Logger LOGGER = Logger.getLogger(NexusSearch.class.getName());
    -  63   -
     
    +  62  0
         public NexusSearch(URL rootURL) {
    +  63  0
             this.rootURL = rootURL;
     64   -
         /**
    -  65   -
          * Creates a NexusSearch for the given repository URL.
    -  66   -
          *
    -  67   -
          * @param rootURL the root URL of the repository on which searches should execute. full URL's are calculated relative to this
    -  68   -
          * URL, so it should end with a /
    -  69   -
          */
    -  70  0
         public NexusSearch(URL rootURL) {
    -  71  0
             this.rootURL = rootURL;
    -  72  
             try {
    -  73  0
                 if (null != Settings.getString(Settings.KEYS.PROXY_SERVER)
    -  74   +  65  0
                 if (null != Settings.getString(Settings.KEYS.PROXY_SERVER)
    +  66  
                         && Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_PROXY)) {
    -  75  0
                     useProxy = true;
    -  76  0
                     LOGGER.fine("Using proxy");
    -  77   +  67  0
                     useProxy = true;
    +  68  0
                     LOGGER.debug("Using proxy");
    +  69  
                 } else {
    -  78  0
                     useProxy = false;
    -  79  0
                     LOGGER.fine("Not using proxy");
    -  80   +  70  0
                     useProxy = false;
    +  71  0
                     LOGGER.debug("Not using proxy");
    +  72  
                 }
    -  81  0
             } catch (InvalidSettingException ise) {
    -  82  0
                 useProxy = false;
    -  83  0
             }
    -  84  0
         }
    -  85   +  73  0
             } catch (InvalidSettingException ise) {
    +  74  0
                 useProxy = false;
    +  75  0
             }
    +  76  0
         }
    +  77  
     
    -  86   +  78  
         /**
    -  87   +  79  
          * Searches the configured Nexus repository for the given sha1 hash. If the artifact is found, a <code>MavenArtifact</code> is
    -  88   +  80  
          * populated with the coordinate information.
    -  89   +  81  
          *
    -  90   +  82  
          * @param sha1 The SHA-1 hash string for which to search
    -  91   +  83  
          * @return the populated Maven coordinates
    -  92   +  84  
          * @throws IOException if it's unable to connect to the specified repository or if the specified artifact is not found.
    -  93   +  85  
          */
    -  94   +  86  
         public MavenArtifact searchSha1(String sha1) throws IOException {
    -  95  0
             if (null == sha1 || !sha1.matches("^[0-9A-Fa-f]{40}$")) {
    -  96  0
                 throw new IllegalArgumentException("Invalid SHA1 format");
    -  97   +  87  0
             if (null == sha1 || !sha1.matches("^[0-9A-Fa-f]{40}$")) {
    +  88  0
                 throw new IllegalArgumentException("Invalid SHA1 format");
    +  89  
             }
    -  98   +  90  
     
    -  99  0
             final URL url = new URL(rootURL, String.format("identify/sha1/%s",
    -  100   +  91  0
             final URL url = new URL(rootURL, String.format("identify/sha1/%s",
    +  92  
                     sha1.toLowerCase()));
    -  101   +  93  
     
    -  102  0
             LOGGER.fine(String.format("Searching Nexus url %s", url.toString()));
    +  94  0
             LOGGER.debug("Searching Nexus url {}", url);
    +  95   +
     
    +  96   +
             // Determine if we need to use a proxy. The rules:
    +  97   +
             // 1) If the proxy is set, AND the setting is set to true, use the proxy
    +  98   +
             // 2) Otherwise, don't use the proxy (either the proxy isn't configured,
    +  99   +
             // or proxy is specifically set to false
    +  100   +
             HttpURLConnection conn;
    +  101  0
             conn = URLConnectionFactory.createHttpURLConnection(url, useProxy);
    +  102  0
             conn.setDoOutput(true);
     103  
     
     104   -
             // Determine if we need to use a proxy. The rules:
    -  105   -
             // 1) If the proxy is set, AND the setting is set to true, use the proxy
    -  106   -
             // 2) Otherwise, don't use the proxy (either the proxy isn't configured,
    -  107   -
             // or proxy is specifically set to false
    -  108   -
             HttpURLConnection conn;
    -  109  0
             conn = URLConnectionFactory.createHttpURLConnection(url, useProxy);
    -  110  0
             conn.setDoOutput(true);
    -  111   -
     
    -  112  
             // JSON would be more elegant, but there's not currently a dependency
    -  113   +  105  
             // on JSON, so don't want to add one just for this
    -  114  0
             conn.addRequestProperty("Accept", "application/xml");
    -  115  0
             conn.connect();
    -  116   +  106  0
             conn.addRequestProperty("Accept", "application/xml");
    +  107  0
             conn.connect();
    +  108  
     
    -  117  0
             if (conn.getResponseCode() == 200) {
    -  118   +  109  0
             if (conn.getResponseCode() == 200) {
    +  110  
                 try {
    -  119  0
                     final DocumentBuilder builder = DocumentBuilderFactory
    -  120   +  111  0
                     final DocumentBuilder builder = DocumentBuilderFactory
    +  112  
                             .newInstance().newDocumentBuilder();
    -  121  0
                     final Document doc = builder.parse(conn.getInputStream());
    -  122  0
                     final XPath xpath = XPathFactory.newInstance().newXPath();
    -  123  0
                     final String groupId = xpath
    -  124   +  113  0
                     final Document doc = builder.parse(conn.getInputStream());
    +  114  0
                     final XPath xpath = XPathFactory.newInstance().newXPath();
    +  115  0
                     final String groupId = xpath
    +  116  
                             .evaluate(
    -  125   +  117  
                                     "/org.sonatype.nexus.rest.model.NexusArtifact/groupId",
    -  126   +  118  
                                     doc);
    -  127  0
                     final String artifactId = xpath.evaluate(
    -  128   +  119  0
                     final String artifactId = xpath.evaluate(
    +  120  
                             "/org.sonatype.nexus.rest.model.NexusArtifact/artifactId",
    -  129   +  121  
                             doc);
    -  130  0
                     final String version = xpath
    +  122  0
                     final String version = xpath
    +  123   +
                             .evaluate(
    +  124   +
                                     "/org.sonatype.nexus.rest.model.NexusArtifact/version",
    +  125   +
                                     doc);
    +  126  0
                     final String link = xpath
    +  127   +
                             .evaluate(
    +  128   +
                                     "/org.sonatype.nexus.rest.model.NexusArtifact/artifactLink",
    +  129   +
                                     doc);
    +  130  0
                     final String pomLink = xpath
     131  
                             .evaluate(
     132   -
                                     "/org.sonatype.nexus.rest.model.NexusArtifact/version",
    +
                                     "/org.sonatype.nexus.rest.model.NexusArtifact/pomLink",
     133  
                                     doc);
    -  134  0
                     final String link = xpath
    -  135   -
                             .evaluate(
    -  136   -
                                     "/org.sonatype.nexus.rest.model.NexusArtifact/artifactLink",
    +  134  0
                     final MavenArtifact ma = new MavenArtifact(groupId, artifactId, version);
    +  135  0
                     if (link != null && !"".equals(link)) {
    +  136  0
                         ma.setArtifactUrl(link);
     137   -
                                     doc);
    -  138  0
                     final String pomLink = xpath
    -  139   -
                             .evaluate(
    +
                     }
    +  138  0
                     if (pomLink != null && !"".equals(pomLink)) {
    +  139  0
                         ma.setPomUrl(pomLink);
     140   -
                                     "/org.sonatype.nexus.rest.model.NexusArtifact/pomLink",
    -  141   -
                                     doc);
    -  142  0
                     final MavenArtifact ma = new MavenArtifact(groupId, artifactId, version);
    -  143  0
                     if (link != null && !"".equals(link)) {
    -  144  0
                         ma.setArtifactUrl(link);
    -  145  
                     }
    -  146  0
                     if (pomLink != null && !"".equals(pomLink)) {
    -  147  0
                         ma.setPomUrl(pomLink);
    -  148   -
                     }
    -  149  0
                     return ma;
    -  150  0
                 } catch (Throwable e) {
    -  151   +  141  0
                     return ma;
    +  142  0
                 } catch (Throwable e) {
    +  143  
                     // Anything else is jacked-up XML stuff that we really can't recover
    -  152   +  144  
                     // from well
    -  153  0
                     throw new IOException(e.getMessage(), e);
    -  154   +  145  0
                     throw new IOException(e.getMessage(), e);
    +  146  
                 }
    -  155  0
             } else if (conn.getResponseCode() == 404) {
    -  156  0
                 throw new FileNotFoundException("Artifact not found in Nexus");
    -  157   +  147  0
             } else if (conn.getResponseCode() == 404) {
    +  148  0
                 throw new FileNotFoundException("Artifact not found in Nexus");
    +  149  
             } else {
    -  158  0
                 final String msg = String.format("Could not connect to Nexus received response code: %d %s",
    -  159   +  150  0
                 LOGGER.debug("Could not connect to Nexus received response code: {} {}",
    +  151  
                         conn.getResponseCode(), conn.getResponseMessage());
    -  160  0
                 LOGGER.fine(msg);
    -  161  0
                 throw new IOException(msg);
    -  162   +  152  0
                 throw new IOException("Could not connect to Nexus");
    +  153  
             }
    -  163   +  154  
         }
    -  164   +  155  
     
    -  165   +  156  
         /**
    -  166   +  157  
          * Do a preflight request to see if the repository is actually working.
    -  167   +  158  
          *
    -  168   +  159  
          * @return whether the repository is listening and returns the /status URL correctly
    -  169   +  160  
          */
    -  170   +  161  
         public boolean preflightRequest() {
    -  171   +  162  
             HttpURLConnection conn;
    -  172   +  163  
             try {
    -  173  0
                 final URL url = new URL(rootURL, "status");
    -  174  0
                 conn = URLConnectionFactory.createHttpURLConnection(url, useProxy);
    -  175  0
                 conn.addRequestProperty("Accept", "application/xml");
    -  176  0
                 conn.connect();
    -  177  0
                 if (conn.getResponseCode() != 200) {
    -  178  0
                     LOGGER.log(Level.WARNING, "Expected 200 result from Nexus, got {0}", conn.getResponseCode());
    -  179  0
                     return false;
    -  180   +  164  0
                 final URL url = new URL(rootURL, "status");
    +  165  0
                 conn = URLConnectionFactory.createHttpURLConnection(url, useProxy);
    +  166  0
                 conn.addRequestProperty("Accept", "application/xml");
    +  167  0
                 conn.connect();
    +  168  0
                 if (conn.getResponseCode() != 200) {
    +  169  0
                     LOGGER.warn("Expected 200 result from Nexus, got {}", conn.getResponseCode());
    +  170  0
                     return false;
    +  171  
                 }
    -  181  0
                 final DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
    -  182  0
                 final Document doc = builder.parse(conn.getInputStream());
    -  183  0
                 if (!"status".equals(doc.getDocumentElement().getNodeName())) {
    -  184  0
                     LOGGER.log(Level.WARNING, "Expected root node name of status, got {0}", doc.getDocumentElement().getNodeName());
    -  185  0
                     return false;
    -  186   +  172  0
                 final DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
    +  173  0
                 final Document doc = builder.parse(conn.getInputStream());
    +  174  0
                 if (!"status".equals(doc.getDocumentElement().getNodeName())) {
    +  175  0
                     LOGGER.warn("Expected root node name of status, got {}", doc.getDocumentElement().getNodeName());
    +  176  0
                     return false;
    +  177  
                 }
    -  187  0
             } catch (Throwable e) {
    -  188  0
                 return false;
    -  189  0
             }
    -  190   +  178  0
             } catch (Throwable e) {
    +  179  0
                 return false;
    +  180  0
             }
    +  181  
     
    -  191  0
             return true;
    -  192   +  182  0
             return true;
    +  183  
         }
    -  193   +  184  
     }
    -  194   +  185  
     
    -  195   +  186  
     // 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 dad0676e7..ed6b2c04a 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  16
         public NugetPackage() {
    +  60  16
         }
     61  
     
     62   @@ -147,8 +147,8 @@
          */
     66  
         public void setId(String id) {
    -  67  1
             this.id = id;
    -  68  1
         }
    +  67  8
             this.id = id;
    +  68  8
         }
     69  
     
     70   @@ -161,7 +161,7 @@
          */
     74  
         public String getId() {
    -  75  1
             return id;
    +  75  8
             return id;
     76  
         }
     77   @@ -176,8 +176,8 @@
          */
     82  
         public void setVersion(String version) {
    -  83  1
             this.version = version;
    -  84  1
         }
    +  83  8
             this.version = version;
    +  84  8
         }
     85  
     
     86   @@ -190,7 +190,7 @@
          */
     90  
         public String getVersion() {
    -  91  1
             return version;
    +  91  8
             return version;
     92  
         }
     93   @@ -205,8 +205,8 @@
          */
     98  
         public void setTitle(String title) {
    -  99  1
             this.title = title;
    -  100  1
         }
    +  99  8
             this.title = title;
    +  100  8
         }
     101  
     
     102   @@ -219,7 +219,7 @@
          */
     106  
         public String getTitle() {
    -  107  1
             return title;
    +  107  8
             return title;
     108  
         }
     109   @@ -234,8 +234,8 @@
          */
     114  
         public void setAuthors(String authors) {
    -  115  1
             this.authors = authors;
    -  116  1
         }
    +  115  8
             this.authors = authors;
    +  116  8
         }
     117  
     
     118   @@ -248,7 +248,7 @@
          */
     122  
         public String getAuthors() {
    -  123  1
             return authors;
    +  123  8
             return authors;
     124  
         }
     125   @@ -263,8 +263,8 @@
          */
     130  
         public void setOwners(String owners) {
    -  131  1
             this.owners = owners;
    -  132  1
         }
    +  131  8
             this.owners = owners;
    +  132  8
         }
     133  
     
     134   @@ -277,7 +277,7 @@
          */
     138  
         public String getOwners() {
    -  139  1
             return owners;
    +  139  8
             return owners;
     140  
         }
     141   @@ -292,8 +292,8 @@
          */
     146  
         public void setLicenseUrl(String licenseUrl) {
    -  147  1
             this.licenseUrl = licenseUrl;
    -  148  1
         }
    +  147  8
             this.licenseUrl = licenseUrl;
    +  148  8
         }
     149  
     
     150   @@ -306,7 +306,7 @@
          */
     154  
         public String getLicenseUrl() {
    -  155  1
             return licenseUrl;
    +  155  8
             return licenseUrl;
     156  
         }
     157   @@ -357,6 +357,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 de0d68e42..48187a7a0 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  8
             super(message);
    +  51  8
         }
     52  
     
     53   @@ -141,12 +141,12 @@
          */
     64  
         public NuspecParseException(String message, Throwable cause) {
    -  65  2
             super(message, cause);
    -  66  2
         }
    +  65  16
             super(message, cause);
    +  66  16
         }
     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 573f635e2..d23fb2c09 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 b11c4b1c6..e5df37207 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  24
     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  24
             if (n != null) {
    +  43  24
                 return n.getTextContent();
     44  
             } else {
     45  0
                 return null;
    @@ -129,32 +129,32 @@
         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  24
                 final Document d = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(stream);
    +  60  16
                 final XPath xpath = XPathFactory.newInstance().newXPath();
    +  61  16
                 final NugetPackage nuspec = new NugetPackage();
     62  
     
    -  63  2
                 if (xpath.evaluate("/package/metadata/id", d, XPathConstants.NODE) == null
    +  63  16
                 if (xpath.evaluate("/package/metadata/id", d, XPathConstants.NODE) == null
     64  
                         || xpath.evaluate("/package/metadata/version", d, XPathConstants.NODE) == null
     65  
                         || xpath.evaluate("/package/metadata/authors", d, XPathConstants.NODE) == null
     66  
                         || xpath.evaluate("/package/metadata/description", d, XPathConstants.NODE) == null) {
    -  67  1
                     throw new NuspecParseException("Invalid Nuspec format");
    +  67  8
                     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  8
                 nuspec.setId(xpath.evaluate("/package/metadata/id", d));
    +  71  8
                 nuspec.setVersion(xpath.evaluate("/package/metadata/version", d));
    +  72  8
                 nuspec.setAuthors(xpath.evaluate("/package/metadata/authors", d));
    +  73  8
                 nuspec.setOwners(getOrNull((Node) xpath.evaluate("/package/metadata/owners", d, XPathConstants.NODE)));
    +  74  8
                 nuspec.setLicenseUrl(getOrNull((Node) xpath.evaluate("/package/metadata/licenseUrl", d, XPathConstants.NODE)));
    +  75  8
                 nuspec.setTitle(getOrNull((Node) xpath.evaluate("/package/metadata/title", d, XPathConstants.NODE)));
    +  76  8
                 return nuspec;
    +  77  16
             } catch (Throwable e) {
    +  78  16
                 throw new NuspecParseException("Unable to parse nuspec", e);
     79  
             }
     80   @@ -163,6 +163,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 bc52905c4..76b7b1265 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 @@ -12,7 +12,7 @@
     
    - +
    Classes in this File Line Coverage Branch Coverage Complexity
    ConnectionFactory
    42%
    59/138
    36%
    11/30
    7
    ConnectionFactory
    33%
    56/166
    29%
    10/34
    7.25
     
    @@ -80,316 +80,317 @@  31  
     import java.sql.Statement;
     32   -
     import java.util.logging.Level;
    -  33   -
     import java.util.logging.Logger;
    -  34  
     import org.owasp.dependencycheck.utils.DBUtils;
    -  35   +  33  
     import org.owasp.dependencycheck.utils.Settings;
    +  34   +
     import org.slf4j.Logger;
    +  35   +
     import org.slf4j.LoggerFactory;
     36  
     
     37  
     /**
     38   -
      * Loads the configured database driver and returns the database connection. If the embedded H2 database is used
    +
      * Loads the configured database driver and returns the database connection. If the embedded H2 database is used obtaining a
     39   -
      * obtaining a connection will ensure the database file exists and that the appropriate table structure has been
    +
      * connection will ensure the database file exists and that the appropriate table structure has been created.
     40   -
      * created.
    -  41  
      *
    -  42   +  41  
      * @author Jeremy Long
    -  43   +  42  
      */
    -  44   +  43  
     public final class ConnectionFactory {
    +  44   +
     
     45   -
     
    +
         /**
     46   -
         /**
    -  47  
          * The Logger.
    -  48   +  47  
          */
    -  49  1
         private static final Logger LOGGER = Logger.getLogger(ConnectionFactory.class.getName());
    +  48  8
         private static final Logger LOGGER = LoggerFactory.getLogger(ConnectionFactory.class);
    +  49   +
         /**
     50   -
         /**
    -  51  
          * The version of the current DB Schema.
    -  52   +  51  
          */
    -  53  1
         public static final String DB_SCHEMA_VERSION = Settings.getString(Settings.KEYS.DB_VERSION);
    +  52  8
         public static final String DB_SCHEMA_VERSION = Settings.getString(Settings.KEYS.DB_VERSION);
    +  53   +
         /**
     54   -
         /**
    -  55  
          * Resource location for SQL file used to create the database schema.
    +  55   +
          */
     56   -
          */
    -  57  
         public static final String DB_STRUCTURE_RESOURCE = "data/initialize.sql";
    +  57   +
         /**
     58   -
         /**
    +
          * Resource location for SQL file used to create the database schema.
     59   -
          * The database driver used to connect to the database.
    +
          */
     60   -
          */
    -  61  1
         private static Driver driver = null;
    +
         public static final String DB_STRUCTURE_UPDATE_RESOURCE = "data/upgrade_%s.sql";
    +  61   +
         /**
     62   -
         /**
    +
          * The database driver used to connect to the database.
     63   -
          * The database connection string.
    -  64  
          */
    -  65  1
         private static String connectionString = null;
    +  64  8
         private static Driver driver = null;
    +  65   +
         /**
     66   -
         /**
    +
          * The database connection string.
     67   -
          * The username to connect to the database.
    -  68  
          */
    -  69  1
         private static String userName = null;
    +  68  8
         private static String connectionString = null;
    +  69   +
         /**
     70   -
         /**
    +
          * The username to connect to the database.
     71   -
          * The password for the database.
    -  72  
          */
    -  73  1
         private static String password = null;
    +  72  8
         private static String userName = null;
    +  73   +
         /**
     74   -
     
    +
          * The password for the database.
     75   -
         /**
    -  76   -
          * Private constructor for this factory class; no instance is ever needed.
    +
          */
    +  76  8
         private static String password = null;
     77   -
          */
    -  78  0
         private ConnectionFactory() {
    -  79  0
         }
    +
     
    +  78   +
         /**
    +  79   +
          * Private constructor for this factory class; no instance is ever needed.
     80   -
     
    -  81   -
         /**
    -  82   -
          * Initializes the connection factory. Ensuring that the appropriate drivers are loaded and that a connection can be
    +
          */
    +  81  0
         private ConnectionFactory() {
    +  82  0
         }
     83   -
          * made successfully.
    +
     
     84   -
          *
    +
         /**
     85   -
          * @throws DatabaseException thrown if we are unable to connect to the database
    +
          * Initializes the connection factory. Ensuring that the appropriate drivers are loaded and that a connection can be made
     86   -
          */
    +
          * successfully.
     87   -
         public static synchronized void initialize() throws DatabaseException {
    +
          *
     88   -
             //this only needs to be called once.
    -  89  4
             if (connectionString != null) {
    -  90  3
                 return;
    +
          * @throws DatabaseException thrown if we are unable to connect to the database
    +  89   +
          */
    +  90   +
         public static synchronized void initialize() throws DatabaseException {
     91   -
             }
    -  92  1
             Connection conn = null;
    -  93   -
             try {
    +
             //this only needs to be called once.
    +  92  64
             if (connectionString != null) {
    +  93  56
                 return;
     94   -
                 //load the driver if necessary
    -  95  1
                 final String driverName = Settings.getString(Settings.KEYS.DB_DRIVER_NAME, "");
    -  96  1
                 if (!driverName.isEmpty()) { //likely need to load the correct driver
    -  97  1
                     LOGGER.log(Level.FINE, "Loading driver: {0}", driverName);
    -  98  1
                     final String driverPath = Settings.getString(Settings.KEYS.DB_DRIVER_PATH, "");
    -  99   -
                     try {
    -  100  1
                         if (!driverPath.isEmpty()) {
    -  101  0
                             LOGGER.log(Level.FINE, "Loading driver from: {0}", driverPath);
    -  102  0
                             driver = DriverLoader.load(driverName, driverPath);
    -  103   -
                         } else {
    -  104  1
                             driver = DriverLoader.load(driverName);
    -  105   -
                         }
    -  106  0
                     } catch (DriverLoadException ex) {
    -  107  0
                         LOGGER.log(Level.FINE, "Unable to load database driver", ex);
    -  108  0
                         throw new DatabaseException("Unable to load database driver");
    -  109  1
                     }
    -  110   -
                 }
    -  111  1
                 userName = Settings.getString(Settings.KEYS.DB_USER, "dcuser");
    -  112   -
                 //yes, yes - hard-coded password - only if there isn't one in the properties file.
    -  113  1
                 password = Settings.getString(Settings.KEYS.DB_PASSWORD, "DC-Pass1337!");
    -  114   -
                 try {
    -  115  1
                     connectionString = Settings.getConnectionString(
    -  116   -
                             Settings.KEYS.DB_CONNECTION_STRING,
    -  117   -
                             Settings.KEYS.DB_FILE_NAME,
    -  118   -
                             Settings.KEYS.DB_VERSION);
    -  119  0
                 } catch (IOException ex) {
    -  120  0
                     LOGGER.log(Level.FINE,
    -  121   -
                             "Unable to retrieve the database connection string", ex);
    -  122  0
                     throw new DatabaseException("Unable to retrieve the database connection string");
    -  123  1
                 }
    -  124  1
                 boolean shouldCreateSchema = false;
    -  125   -
                 try {
    -  126  1
                     if (connectionString.startsWith("jdbc:h2:file:")) { //H2
    -  127  1
                         shouldCreateSchema = !h2DataFileExists();
    -  128  1
                         LOGGER.log(Level.FINE, "Need to create DB Structure: {0}", shouldCreateSchema);
    -  129   -
                     }
    -  130  0
                 } catch (IOException ioex) {
    -  131  0
                     LOGGER.log(Level.FINE, "Unable to verify database exists", ioex);
    -  132  0
                     throw new DatabaseException("Unable to verify database exists");
    -  133  1
                 }
    -  134  1
                 LOGGER.log(Level.FINE, "Loading database connection");
    -  135  1
                 LOGGER.log(Level.FINE, "Connection String: {0}", connectionString);
    -  136  1
                 LOGGER.log(Level.FINE, "Database User: {0}", userName);
    -  137   -
     
    -  138   -
                 try {
    -  139  1
                     conn = DriverManager.getConnection(connectionString, userName, password);
    -  140  0
                 } catch (SQLException ex) {
    -  141  0
                     if (ex.getMessage().contains("java.net.UnknownHostException") && connectionString.contains("AUTO_SERVER=TRUE;")) {
    -  142  0
                         connectionString = connectionString.replace("AUTO_SERVER=TRUE;", "");
    -  143   -
                         try {
    -  144  0
                             conn = DriverManager.getConnection(connectionString, userName, password);
    -  145  0
                             Settings.setString(Settings.KEYS.DB_CONNECTION_STRING, connectionString);
    -  146  0
                             LOGGER.log(Level.FINE,
    -  147   -
                                     "Unable to start the database in server mode; reverting to single user mode");
    -  148  0
                         } catch (SQLException sqlex) {
    -  149  0
                             LOGGER.log(Level.FINE, "Unable to connect to the database", ex);
    -  150  0
                             throw new DatabaseException("Unable to connect to the database");
    -  151  0
                         }
    -  152   -
                     } else {
    -  153  0
                         LOGGER.log(Level.FINE, "Unable to connect to the database", ex);
    -  154  0
                         throw new DatabaseException("Unable to connect to the database");
    -  155   -
                     }
    -  156  1
                 }
    -  157   -
     
    -  158  1
                 if (shouldCreateSchema) {
    -  159   -
                     try {
    -  160  0
                         createTables(conn);
    -  161  0
                     } catch (DatabaseException dex) {
    -  162  0
                         LOGGER.log(Level.FINE, null, dex);
    -  163  0
                         throw new DatabaseException("Unable to create the database structure");
    -  164  0
                     }
    -  165   -
                 } else {
    -  166   -
                     try {
    -  167  1
                         ensureSchemaVersion(conn);
    -  168  0
                     } catch (DatabaseException dex) {
    -  169  0
                         LOGGER.log(Level.FINE, null, dex);
    -  170  0
                         throw new DatabaseException("Database schema does not match this version of dependency-check");
    -  171  1
                     }
    -  172   -
                 }
    -  173   -
             } finally {
    -  174  1
                 if (conn != null) {
    -  175   -
                     try {
    -  176  1
                         conn.close();
    -  177  0
                     } catch (SQLException ex) {
    -  178  0
                         LOGGER.log(Level.FINE, "An error occurred closing the connection", ex);
    -  179  1
                     }
    -  180   -
                 }
    -  181  
             }
    -  182  1
         }
    -  183   -
     
    -  184   -
         /**
    -  185   -
          * Cleans up resources and unloads any registered database drivers. This needs to be called to ensure the driver is
    -  186   -
          * unregistered prior to the finalize method being called as during shutdown the class loader used to load the
    -  187   -
          * driver may be unloaded prior to the driver being de-registered.
    -  188   -
          */
    -  189   -
         public static synchronized void cleanup() {
    -  190  0
             if (driver != null) {
    -  191   -
                 try {
    -  192  0
                     DriverManager.deregisterDriver(driver);
    -  193  0
                 } catch (SQLException ex) {
    -  194  0
                     LOGGER.log(Level.FINE, "An error occurred unloading the database driver", ex);
    -  195  0
                 } catch (Throwable unexpected) {
    -  196  0
                     LOGGER.log(Level.FINE,
    -  197   -
                             "An unexpected throwable occurred unloading the database driver", unexpected);
    -  198  0
                 }
    -  199  0
                 driver = null;
    -  200   -
             }
    -  201  0
             connectionString = null;
    -  202  0
             userName = null;
    -  203  0
             password = null;
    -  204  0
         }
    -  205   -
     
    -  206   -
         /**
    -  207   -
          * Constructs a new database connection object per the database configuration.
    -  208   -
          *
    -  209   -
          * @return a database connection object
    -  210   -
          * @throws DatabaseException thrown if there is an exception loading the database connection
    -  211   -
          */
    -  212   -
         public static Connection getConnection() throws DatabaseException {
    -  213  3
             initialize();
    -  214  3
             Connection conn = null;
    -  215   +  95  8
             Connection conn = null;
    +  96  
             try {
    -  216  3
                 conn = DriverManager.getConnection(connectionString, userName, password);
    -  217  0
             } catch (SQLException ex) {
    -  218  0
                 LOGGER.log(Level.FINE, null, ex);
    -  219  0
                 throw new DatabaseException("Unable to connect to the database");
    -  220  3
             }
    -  221  3
             return conn;
    -  222   -
         }
    -  223   +  97   +
                 //load the driver if necessary
    +  98  8
                 final String driverName = Settings.getString(Settings.KEYS.DB_DRIVER_NAME, "");
    +  99  8
                 if (!driverName.isEmpty()) { //likely need to load the correct driver
    +  100  8
                     LOGGER.debug("Loading driver: {}", driverName);
    +  101  8
                     final String driverPath = Settings.getString(Settings.KEYS.DB_DRIVER_PATH, "");
    +  102   +
                     try {
    +  103  8
                         if (!driverPath.isEmpty()) {
    +  104  0
                             LOGGER.debug("Loading driver from: {}", driverPath);
    +  105  0
                             driver = DriverLoader.load(driverName, driverPath);
    +  106   +
                         } else {
    +  107  8
                             driver = DriverLoader.load(driverName);
    +  108   +
                         }
    +  109  0
                     } catch (DriverLoadException ex) {
    +  110  0
                         LOGGER.debug("Unable to load database driver", ex);
    +  111  0
                         throw new DatabaseException("Unable to load database driver");
    +  112  8
                     }
    +  113   +
                 }
    +  114  8
                 userName = Settings.getString(Settings.KEYS.DB_USER, "dcuser");
    +  115   +
                 //yes, yes - hard-coded password - only if there isn't one in the properties file.
    +  116  8
                 password = Settings.getString(Settings.KEYS.DB_PASSWORD, "DC-Pass1337!");
    +  117   +
                 try {
    +  118  8
                     connectionString = Settings.getConnectionString(
    +  119   +
                             Settings.KEYS.DB_CONNECTION_STRING,
    +  120   +
                             Settings.KEYS.DB_FILE_NAME);
    +  121  0
                 } catch (IOException ex) {
    +  122  0
                     LOGGER.debug(
    +  123   +
                             "Unable to retrieve the database connection string", ex);
    +  124  0
                     throw new DatabaseException("Unable to retrieve the database connection string");
    +  125  8
                 }
    +  126  8
                 boolean shouldCreateSchema = false;
    +  127   +
                 try {
    +  128  8
                     if (connectionString.startsWith("jdbc:h2:file:")) { //H2
    +  129  8
                         shouldCreateSchema = !h2DataFileExists();
    +  130  8
                         LOGGER.debug("Need to create DB Structure: {}", shouldCreateSchema);
    +  131   +
                     }
    +  132  0
                 } catch (IOException ioex) {
    +  133  0
                     LOGGER.debug("Unable to verify database exists", ioex);
    +  134  0
                     throw new DatabaseException("Unable to verify database exists");
    +  135  8
                 }
    +  136  8
                 LOGGER.debug("Loading database connection");
    +  137  8
                 LOGGER.debug("Connection String: {}", connectionString);
    +  138  8
                 LOGGER.debug("Database User: {}", userName);
    +  139  
     
    -  224   +  140   +
                 try {
    +  141  8
                     conn = DriverManager.getConnection(connectionString, userName, password);
    +  142  0
                 } catch (SQLException ex) {
    +  143  0
                     if (ex.getMessage().contains("java.net.UnknownHostException") && connectionString.contains("AUTO_SERVER=TRUE;")) {
    +  144  0
                         connectionString = connectionString.replace("AUTO_SERVER=TRUE;", "");
    +  145   +
                         try {
    +  146  0
                             conn = DriverManager.getConnection(connectionString, userName, password);
    +  147  0
                             Settings.setString(Settings.KEYS.DB_CONNECTION_STRING, connectionString);
    +  148  0
                             LOGGER.debug(
    +  149   +
                                     "Unable to start the database in server mode; reverting to single user mode");
    +  150  0
                         } catch (SQLException sqlex) {
    +  151  0
                             LOGGER.debug("Unable to connect to the database", ex);
    +  152  0
                             throw new DatabaseException("Unable to connect to the database");
    +  153  0
                         }
    +  154   +
                     } else {
    +  155  0
                         LOGGER.debug("Unable to connect to the database", ex);
    +  156  0
                         throw new DatabaseException("Unable to connect to the database");
    +  157   +
                     }
    +  158  8
                 }
    +  159   +
     
    +  160  8
                 if (shouldCreateSchema) {
    +  161   +
                     try {
    +  162  0
                         createTables(conn);
    +  163  0
                     } catch (DatabaseException dex) {
    +  164  0
                         LOGGER.debug("", dex);
    +  165  0
                         throw new DatabaseException("Unable to create the database structure");
    +  166  0
                     }
    +  167   +
                 }
    +  168   +
                 try {
    +  169  8
                     ensureSchemaVersion(conn);
    +  170  0
                 } catch (DatabaseException dex) {
    +  171  0
                     LOGGER.debug("", dex);
    +  172  0
                     throw new DatabaseException("Database schema does not match this version of dependency-check", dex);
    +  173  8
                 }
    +  174   +
             } finally {
    +  175  8
                 if (conn != null) {
    +  176   +
                     try {
    +  177  8
                         conn.close();
    +  178  0
                     } catch (SQLException ex) {
    +  179  0
                         LOGGER.debug("An error occurred closing the connection", ex);
    +  180  8
                     }
    +  181   +
                 }
    +  182   +
             }
    +  183  8
         }
    +  184   +
     
    +  185  
         /**
    -  225   -
          * Determines if the H2 database file exists. If it does not exist then the data structure will need to be created.
    -  226   -
          *
    -  227   -
          * @return true if the H2 database file does not exist; otherwise false
    -  228   -
          * @throws IOException thrown if the data directory does not exist and cannot be created
    -  229   +  186   +
          * Cleans up resources and unloads any registered database drivers. This needs to be called to ensure the driver is
    +  187   +
          * unregistered prior to the finalize method being called as during shutdown the class loader used to load the driver may be
    +  188   +
          * unloaded prior to the driver being de-registered.
    +  189  
          */
    +  190   +
         public static synchronized void cleanup() {
    +  191  0
             if (driver != null) {
    +  192   +
                 try {
    +  193  0
                     DriverManager.deregisterDriver(driver);
    +  194  0
                 } catch (SQLException ex) {
    +  195  0
                     LOGGER.debug("An error occurred unloading the database driver", ex);
    +  196  0
                 } catch (Throwable unexpected) {
    +  197  0
                     LOGGER.debug(
    +  198   +
                             "An unexpected throwable occurred unloading the database driver", unexpected);
    +  199  0
                 }
    +  200  0
                 driver = null;
    +  201   +
             }
    +  202  0
             connectionString = null;
    +  203  0
             userName = null;
    +  204  0
             password = null;
    +  205  0
         }
    +  206   +
     
    +  207   +
         /**
    +  208   +
          * Constructs a new database connection object per the database configuration.
    +  209   +
          *
    +  210   +
          * @return a database connection object
    +  211   +
          * @throws DatabaseException thrown if there is an exception loading the database connection
    +  212   +
          */
    +  213   +
         public static Connection getConnection() throws DatabaseException {
    +  214  48
             initialize();
    +  215  48
             Connection conn = null;
    +  216   +
             try {
    +  217  48
                 conn = DriverManager.getConnection(connectionString, userName, password);
    +  218  0
             } catch (SQLException ex) {
    +  219  0
                 LOGGER.debug("", ex);
    +  220  0
                 throw new DatabaseException("Unable to connect to the database");
    +  221  48
             }
    +  222  48
             return conn;
    +  223   +
         }
    +  224   +
     
    +  225   +
         /**
    +  226   +
          * Determines if the H2 database file exists. If it does not exist then the data structure will need to be created.
    +  227   +
          *
    +  228   +
          * @return true if the H2 database file does not exist; otherwise false
    +  229   +
          * @throws IOException thrown if the data directory does not exist and cannot be created
     230   +
          */
    +  231  
         private static boolean h2DataFileExists() throws IOException {
    -  231  1
             final File dir = Settings.getDataDirectory();
    -  232  1
             final String name = Settings.getString(Settings.KEYS.DB_FILE_NAME);
    -  233  1
             final String fileName = String.format(name, DB_SCHEMA_VERSION);
    -  234  1
             final File file = new File(dir, fileName);
    -  235  1
             return file.exists();
    +  232  8
             final File dir = Settings.getDataDirectory();
    +  233  8
             final String fileName = Settings.getString(Settings.KEYS.DB_FILE_NAME);
    +  234  8
             final File file = new File(dir, fileName);
    +  235  8
             return file.exists();
     236  
         }
     237   @@ -408,7 +409,7 @@
          */
     244  
         private static void createTables(Connection conn) throws DatabaseException {
    -  245  0
             LOGGER.log(Level.FINE, "Creating database structure");
    +  245  0
             LOGGER.debug("Creating database structure");
     246  
             InputStream is;
     247   @@ -432,7 +433,7 @@  260  0
                     statement = conn.createStatement();
     261  0
                     statement.execute(sb.toString());
     262  0
                 } catch (SQLException ex) {
    -  263  0
                     LOGGER.log(Level.FINE, null, ex);
    +  263  0
                     LOGGER.debug("", ex);
     264  0
                     throw new DatabaseException("Unable to create database statement", ex);
     265  
                 } finally {
    @@ -447,7 +448,7 @@
                     try {
     273  0
                         in.close();
     274  0
                     } catch (IOException ex) {
    -  275  0
                         LOGGER.log(Level.FINEST, null, ex);
    +  275  0
                         LOGGER.trace("", ex);
     276  0
                     }
     277  
                 }
    @@ -459,46 +460,125 @@  281  
         /**
     282   -
          * Uses the provided connection to check the specified schema version within the database.
    +
          * Updates the database schema by loading the upgrade script for the version specified. The intended use is that if the
     283   -
          *
    +
          * current schema version is 2.9 then we would call updateSchema(conn, "2.9"). This would load the upgrade_2.9.sql file and
     284   -
          * @param conn the database connection object
    +
          * execute it against the database. The upgrade script must update the 'version' in the properties table.
     285   -
          * @throws DatabaseException thrown if the schema version is not compatible with this version of dependency-check
    +
          *
     286   -
          */
    +
          * @param conn the database connection object
     287   -
         private static void ensureSchemaVersion(Connection conn) throws DatabaseException {
    -  288  1
             ResultSet rs = null;
    -  289  1
             CallableStatement cs = null;
    +
          * @param schema the current schema version that is being upgraded
    +  288   +
          * @throws DatabaseException thrown if there is an exception upgrading the database schema
    +  289   +
          */
     290   +
         private static void updateSchema(Connection conn, String schema) throws DatabaseException {
    +  291  0
             LOGGER.debug("Updating database structure");
    +  292   +
             InputStream is;
    +  293   +
             InputStreamReader reader;
    +  294  0
             BufferedReader in = null;
    +  295  0
             String updateFile = null;
    +  296  
             try {
    -  291  1
                 cs = conn.prepareCall("SELECT value FROM properties WHERE id = 'version'");
    -  292  1
                 rs = cs.executeQuery();
    -  293  1
                 if (rs.next()) {
    -  294  1
                     final boolean isWrongSchema = !DB_SCHEMA_VERSION.equals(rs.getString(1));
    -  295  1
                     if (isWrongSchema) {
    -  296  0
                         throw new DatabaseException("Incorrect database schema; unable to continue");
    -  297   -
                     }
    -  298  1
                 } else {
    -  299  0
                     throw new DatabaseException("Database schema is missing");
    -  300   +  297  0
                 updateFile = String.format(DB_STRUCTURE_UPDATE_RESOURCE, schema);
    +  298  0
                 is = ConnectionFactory.class.getClassLoader().getResourceAsStream(updateFile);
    +  299  0
                 if (is == null) {
    +  300  0
                     throw new DatabaseException(String.format("Unable to load update file '%s'", updateFile));
    +  301  
                 }
    -  301  0
             } catch (SQLException ex) {
    -  302  0
                 LOGGER.log(Level.FINE, null, ex);
    -  303  0
                 throw new DatabaseException("Unable to check the database schema version");
    -  304   +  302  0
                 reader = new InputStreamReader(is, "UTF-8");
    +  303  0
                 in = new BufferedReader(reader);
    +  304  0
                 final StringBuilder sb = new StringBuilder(2110);
    +  305   +
                 String tmp;
    +  306  0
                 while ((tmp = in.readLine()) != null) {
    +  307  0
                     sb.append(tmp);
    +  308   +
                 }
    +  309  0
                 Statement statement = null;
    +  310   +
                 try {
    +  311  0
                     statement = conn.createStatement();
    +  312  0
                     statement.execute(sb.toString());
    +  313  0
                 } catch (SQLException ex) {
    +  314  0
                     LOGGER.debug("", ex);
    +  315  0
                     throw new DatabaseException("Unable to update database schema", ex);
    +  316   +
                 } finally {
    +  317  0
                     DBUtils.closeStatement(statement);
    +  318  0
                 }
    +  319  0
             } catch (IOException ex) {
    +  320  0
                 final String msg = String.format("Upgrade SQL file does not exist: %s", updateFile);
    +  321  0
                 throw new DatabaseException(msg, ex);
    +  322  
             } finally {
    -  305  1
                 DBUtils.closeResultSet(rs);
    -  306  1
                 DBUtils.closeStatement(cs);
    -  307  1
             }
    -  308  1
         }
    -  309   +  323  0
                 if (in != null) {
    +  324   +
                     try {
    +  325  0
                         in.close();
    +  326  0
                     } catch (IOException ex) {
    +  327  0
                         LOGGER.trace("", ex);
    +  328  0
                     }
    +  329   +
                 }
    +  330   +
             }
    +  331  0
         }
    +  332   +
     
    +  333   +
         /**
    +  334   +
          * Uses the provided connection to check the specified schema version within the database.
    +  335   +
          *
    +  336   +
          * @param conn the database connection object
    +  337   +
          * @throws DatabaseException thrown if the schema version is not compatible with this version of dependency-check
    +  338   +
          */
    +  339   +
         private static void ensureSchemaVersion(Connection conn) throws DatabaseException {
    +  340  8
             ResultSet rs = null;
    +  341  8
             CallableStatement cs = null;
    +  342   +
             try {
    +  343   +
                 //TODO convert this to use DatabaseProperties
    +  344  8
                 cs = conn.prepareCall("SELECT value FROM properties WHERE id = 'version'");
    +  345  8
                 rs = cs.executeQuery();
    +  346  8
                 if (rs.next()) {
    +  347  8
                     if (!DB_SCHEMA_VERSION.equals(rs.getString(1))) {
    +  348  0
                         LOGGER.debug("Current Schema: " + DB_SCHEMA_VERSION);
    +  349  0
                         LOGGER.debug("DB Schema: " + rs.getString(1));
    +  350  0
                         updateSchema(conn, rs.getString(1));
    +  351   +
                     }
    +  352   +
                 } else {
    +  353  0
                     throw new DatabaseException("Database schema is missing");
    +  354   +
                 }
    +  355  0
             } catch (SQLException ex) {
    +  356  0
                 LOGGER.debug("", ex);
    +  357  0
                 throw new DatabaseException("Unable to check the database schema version");
    +  358   +
             } finally {
    +  359  8
                 DBUtils.closeResultSet(rs);
    +  360  8
                 DBUtils.closeStatement(cs);
    +  361  8
             }
    +  362  8
         }
    +  363  
     }
    - + 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 60468195b..fa978ff08 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 @@ -117,6 +117,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 7f140c69e..2091a9b1c 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
    45%
    193/425
    53%
    70/132
    5.714
    CveDB
    44%
    196/437
    55%
    73/132
    5.391
     
    @@ -60,1116 +60,1170 @@  21  
     import java.io.UnsupportedEncodingException;
     22   -
     import java.sql.Connection;
    +
     import java.sql.CallableStatement;
     23   -
     import java.sql.PreparedStatement;
    +
     import java.sql.Connection;
     24   -
     import java.sql.ResultSet;
    +
     import java.sql.PreparedStatement;
     25   -
     import java.sql.SQLException;
    +
     import java.sql.ResultSet;
     26   -
     import java.sql.Statement;
    +
     import java.sql.SQLException;
     27   -
     import java.util.ArrayList;
    +
     import java.sql.Statement;
     28   -
     import java.util.HashMap;
    +
     import java.util.ArrayList;
     29   -
     import java.util.HashSet;
    +
     import java.util.HashMap;
     30   -
     import java.util.List;
    +
     import java.util.HashSet;
     31   -
     import java.util.Map;
    +
     import java.util.List;
     32   -
     import java.util.Map.Entry;
    +
     import java.util.Map;
     33   -
     import java.util.Properties;
    +
     import java.util.Map.Entry;
     34   -
     import java.util.ResourceBundle;
    +
     import java.util.Properties;
     35   -
     import java.util.Set;
    +
     import java.util.ResourceBundle;
     36   -
     import java.util.logging.Level;
    +
     import java.util.Set;
     37   -
     import java.util.logging.Logger;
    -  38  
     import org.owasp.dependencycheck.data.cwe.CweDB;
    -  39   +  38  
     import org.owasp.dependencycheck.dependency.Reference;
    -  40   +  39  
     import org.owasp.dependencycheck.dependency.Vulnerability;
    -  41   +  40  
     import org.owasp.dependencycheck.dependency.VulnerableSoftware;
    -  42   +  41  
     import org.owasp.dependencycheck.utils.DBUtils;
    -  43   +  42  
     import org.owasp.dependencycheck.utils.DependencyVersion;
    -  44   +  43  
     import org.owasp.dependencycheck.utils.DependencyVersionUtil;
    -  45   +  44  
     import org.owasp.dependencycheck.utils.Pair;
    -  46   +  45  
     import org.owasp.dependencycheck.utils.Settings;
    +  46   +
     import org.slf4j.Logger;
     47   -
     
    +
     import org.slf4j.LoggerFactory;
     48   -
     /**
    +
     
     49   -
      * The database holding information about the NVD CVE data.
    +
     /**
     50   -
      *
    +
      * The database holding information about the NVD CVE data.
     51   -
      * @author Jeremy Long
    +
      *
     52   -
      */
    +
      * @author Jeremy Long
     53   -
     public class CveDB {
    +
      */
     54   -
     
    +
     public class CveDB {
     55   -
         /**
    +
     
     56   -
          * The logger.
    +
         /**
     57   +
          * The logger.
    +  58  
          */
    -  58  1
         private static final Logger LOGGER = Logger.getLogger(CveDB.class.getName());
    -  59   -
         /**
    +  59  8
         private static final Logger LOGGER = LoggerFactory.getLogger(CveDB.class);
     60   -
          * Database connection
    +
         /**
     61   -
          */
    +
          * Database connection
     62   -
         private Connection conn;
    +
          */
     63   -
         /**
    +
         private Connection conn;
     64   -
          * The bundle of statements used when accessing the database.
    +
         /**
     65   +
          * The bundle of statements used when accessing the database.
    +  66  
          */
    -  66  3
         private ResourceBundle statementBundle = null;
    -  67   -
     
    +  67  48
         private ResourceBundle statementBundle = null;
     68   -
         /**
    +
     
     69   -
          * Creates a new CveDB object and opens the database connection. Note, the connection must be closed by the caller by calling
    +
         /**
     70   -
          * the close method.
    +
          * Creates a new CveDB object and opens the database connection. Note, the connection must be closed by the caller by calling
     71   -
          *
    +
          * the close method.
     72   -
          * @throws DatabaseException thrown if there is an exception opening the database.
    +
          *
     73   -
          */
    +
          * @throws DatabaseException thrown if there is an exception opening the database.
     74   +
          */
    +  75  
         public CveDB() throws DatabaseException {
    -  75  3
             super();
    -  76  3
             statementBundle = java.util.ResourceBundle.getBundle("data/dbStatements");
    -  77   +  76  48
             super();
    +  77  48
             statementBundle = ResourceBundle.getBundle("data/dbStatements");
    +  78  
             try {
    -  78  3
                 open();
    -  79  3
                 databaseProperties = new DatabaseProperties(this);
    -  80  0
             } catch (DatabaseException ex) {
    -  81  0
                 throw ex;
    -  82  3
             }
    -  83  3
         }
    -  84   -
     
    +  79  48
                 open();
    +  80  48
                 databaseProperties = new DatabaseProperties(this);
    +  81  0
             } catch (DatabaseException ex) {
    +  82  0
                 throw ex;
    +  83  48
             }
    +  84  48
         }
     85   -
         /**
    +
     
     86   -
          * Returns the database connection.
    +
         /**
     87   -
          *
    +
          * Returns the database connection.
     88   -
          * @return the database connection
    +
          *
     89   -
          */
    +
          * @return the database connection
     90   +
          */
    +  91  
         protected Connection getConnection() {
    -  91  32
             return conn;
    -  92   -
         }
    +  92  296
             return conn;
     93   -
     
    +
         }
     94   -
         /**
    +
     
     95   -
          * Opens the database connection. If the database does not exist, it will create a new one.
    +
         /**
     96   -
          *
    +
          * Opens the database connection. If the database does not exist, it will create a new one.
     97   -
          * @throws DatabaseException thrown if there is an error opening the database connection
    +
          *
     98   -
          */
    +
          * @throws DatabaseException thrown if there is an error opening the database connection
     99   +
          */
    +  100  
         public final void open() throws DatabaseException {
    -  100  6
             if (!isOpen()) {
    -  101  3
                 conn = ConnectionFactory.getConnection();
    -  102   +  101  96
             if (!isOpen()) {
    +  102  48
                 conn = ConnectionFactory.getConnection();
    +  103  
             }
    -  103  6
         }
    -  104   -
     
    +  104  96
         }
     105   -
         /**
    +
     
     106   -
          * Closes the DB4O database. Close should be called on this object when it is done being used.
    +
         /**
     107   -
          */
    +
          * Closes the DB4O database. Close should be called on this object when it is done being used.
     108   +
          */
    +  109  
         public void close() {
    -  109  5
             if (conn != null) {
    -  110   +  110  62
             if (conn != null) {
    +  111  
                 try {
    -  111  3
                     conn.close();
    -  112  0
                 } catch (SQLException ex) {
    -  113  0
                     final String msg = "There was an error attempting to close the CveDB, see the log for more details.";
    -  114  0
                     LOGGER.log(Level.SEVERE, msg);
    -  115  0
                     LOGGER.log(Level.FINE, null, ex);
    +  112  48
                     conn.close();
    +  113  0
                 } catch (SQLException ex) {
    +  114  0
                     LOGGER.error("There was an error attempting to close the CveDB, see the log for more details.");
    +  115  0
                     LOGGER.debug("", ex);
     116  0
                 } catch (Throwable ex) {
    -  117  0
                     final String msg = "There was an exception attempting to close the CveDB, see the log for more details.";
    -  118  0
                     LOGGER.log(Level.SEVERE, msg);
    -  119  0
                     LOGGER.log(Level.FINE, null, ex);
    -  120  3
                 }
    -  121  3
                 conn = null;
    -  122   +  117  0
                     LOGGER.error("There was an exception attempting to close the CveDB, see the log for more details.");
    +  118  0
                     LOGGER.debug("", ex);
    +  119  48
                 }
    +  120  48
                 conn = null;
    +  121  
             }
    -  123  5
         }
    +  122  62
         }
    +  123   +
     
     124   -
     
    +
         /**
     125   -
         /**
    -  126  
          * Returns whether the database connection is open or closed.
    +  126   +
          *
     127   -
          *
    -  128  
          * @return whether the database connection is open or closed
    +  128   +
          */
     129   -
          */
    -  130  
         public boolean isOpen() {
    -  131  6
             return conn != null;
    +  130  96
             return conn != null;
    +  131   +
         }
     132   -
         }
    +
     
     133   -
     
    +
         /**
     134   -
         /**
    -  135  
          * Commits all completed transactions.
    +  135   +
          *
     136   -
          *
    -  137  
          * @throws SQLException thrown if a SQL Exception occurs
    +  137   +
          */
     138   -
          */
    -  139  
         public void commit() throws SQLException {
    -  140   +  139  
             //temporary remove this as autocommit is on.
    -  141   +  140  
             //if (conn != null) {
    -  142   +  141  
             //    conn.commit();
    -  143   +  142  
             //}
    -  144  0
         }
    +  143  0
         }
    +  144   +
     
     145   -
     
    +
         /**
     146   -
         /**
    -  147  
          * Cleans up the object and ensures that "close" has been called.
    +  147   +
          *
     148   -
          *
    -  149  
          * @throws Throwable thrown if there is a problem
    +  149   +
          */
     150   -
          */
    -  151  
         @Override
    -  152   +  151  
         @SuppressWarnings("FinalizeDeclaration")
    -  153   +  152  
         protected void finalize() throws Throwable {
    -  154  2
             LOGGER.log(Level.FINE, "Entering finalize");
    -  155  2
             close();
    -  156  2
             super.finalize();
    -  157  2
         }
    +  153  14
             LOGGER.debug("Entering finalize");
    +  154  14
             close();
    +  155  14
             super.finalize();
    +  156  14
         }
    +  157   +
         /**
     158   -
         /**
    -  159  
          * Database properties object containing the 'properties' from the database table.
    +  159   +
          */
     160   -
          */
    -  161  
         private DatabaseProperties databaseProperties;
    +  161   +
     
     162   -
     
    +
         /**
     163   -
         /**
    -  164  
          * Get the value of databaseProperties.
    +  164   +
          *
     165   -
          *
    -  166  
          * @return the value of databaseProperties
    +  166   +
          */
     167   -
          */
    -  168  
         public DatabaseProperties getDatabaseProperties() {
    -  169  0
             return databaseProperties;
    +  168  24
             return databaseProperties;
    +  169   +
         }
     170   -
         }
    +
     
     171   -
     
    +
         /**
     172   -
         /**
    -  173  
          * Searches the CPE entries in the database and retrieves all entries for a given vendor and product combination. The returned
    -  174   +  173  
          * list will include all versions of the product that are registered in the NVD CVE data.
    +  174   +
          *
     175   -
          *
    -  176  
          * @param vendor the identified vendor name of the dependency being analyzed
    -  177   +  176  
          * @param product the identified name of the product of the dependency being analyzed
    -  178   +  177  
          * @return a set of vulnerable software
    +  178   +
          */
     179   -
          */
    -  180  
         public Set<VulnerableSoftware> getCPEs(String vendor, String product) {
    -  181  2
             final Set<VulnerableSoftware> cpe = new HashSet<VulnerableSoftware>();
    -  182  2
             ResultSet rs = null;
    -  183  2
             PreparedStatement ps = null;
    -  184   +  180  24
             final Set<VulnerableSoftware> cpe = new HashSet<VulnerableSoftware>();
    +  181  24
             ResultSet rs = null;
    +  182  24
             PreparedStatement ps = null;
    +  183  
             try {
    -  185  2
                 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_CPE_ENTRIES"));
    -  186  2
                 ps.setString(1, vendor);
    -  187  2
                 ps.setString(2, product);
    -  188  2
                 rs = ps.executeQuery();
    -  189   +  184  24
                 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_CPE_ENTRIES"));
    +  185  24
                 ps.setString(1, vendor);
    +  186  24
                 ps.setString(2, product);
    +  187  24
                 rs = ps.executeQuery();
    +  188  
     
    -  190  80
                 while (rs.next()) {
    -  191  78
                     final VulnerableSoftware vs = new VulnerableSoftware();
    -  192  78
                     vs.setCpe(rs.getString(1));
    -  193  78
                     cpe.add(vs);
    -  194  78
                 }
    -  195  0
             } catch (SQLException ex) {
    -  196  0
                 final String msg = "An unexpected SQL Exception occurred; please see the verbose log for more details.";
    -  197  0
                 LOGGER.log(Level.SEVERE, msg);
    -  198  0
                 LOGGER.log(Level.FINE, null, ex);
    -  199   +  189  896
                 while (rs.next()) {
    +  190  872
                     final VulnerableSoftware vs = new VulnerableSoftware();
    +  191  872
                     vs.setCpe(rs.getString(1));
    +  192  872
                     cpe.add(vs);
    +  193  872
                 }
    +  194  0
             } catch (SQLException ex) {
    +  195  0
                 LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details.");
    +  196  0
                 LOGGER.debug("", ex);
    +  197  
             } finally {
    -  200  2
                 DBUtils.closeResultSet(rs);
    -  201  2
                 DBUtils.closeStatement(ps);
    -  202  2
             }
    -  203  2
             return cpe;
    +  198  24
                 DBUtils.closeResultSet(rs);
    +  199  24
                 DBUtils.closeStatement(ps);
    +  200  24
             }
    +  201  24
             return cpe;
    +  202   +
         }
    +  203   +
     
     204   -
         }
    +
         /**
     205   -
     
    -  206   -
         /**
    -  207  
          * Returns the entire list of vendor/product combinations.
    -  208   +  206  
          *
    -  209   +  207  
          * @return the entire list of vendor/product combinations
    -  210   +  208  
          * @throws DatabaseException thrown when there is an error retrieving the data from the DB
    -  211   +  209  
          */
    -  212   +  210  
         public Set<Pair<String, String>> getVendorProductList() throws DatabaseException {
    -  213  1
             final Set<Pair<String, String>> data = new HashSet<Pair<String, String>>();
    -  214  1
             ResultSet rs = null;
    -  215  1
             PreparedStatement ps = null;
    -  216   +  211  8
             final Set<Pair<String, String>> data = new HashSet<Pair<String, String>>();
    +  212  8
             ResultSet rs = null;
    +  213  8
             PreparedStatement ps = null;
    +  214  
             try {
    -  217  1
                 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_VENDOR_PRODUCT_LIST"));
    -  218  1
                 rs = ps.executeQuery();
    -  219  24880
                 while (rs.next()) {
    -  220  24879
                     data.add(new Pair<String, String>(rs.getString(1), rs.getString(2)));
    -  221   +  215  8
                 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_VENDOR_PRODUCT_LIST"));
    +  216  8
                 rs = ps.executeQuery();
    +  217  201186
                 while (rs.next()) {
    +  218  201178
                     data.add(new Pair<String, String>(rs.getString(1), rs.getString(2)));
    +  219  
                 }
    -  222  0
             } catch (SQLException ex) {
    -  223  0
                 final String msg = "An unexpected SQL Exception occurred; please see the verbose log for more details.";
    -  224  0
                 throw new DatabaseException(msg, ex);
    -  225   +  220  0
             } catch (SQLException ex) {
    +  221  0
                 final String msg = "An unexpected SQL Exception occurred; please see the verbose log for more details.";
    +  222  0
                 throw new DatabaseException(msg, ex);
    +  223  
             } finally {
    -  226  1
                 DBUtils.closeResultSet(rs);
    -  227  1
                 DBUtils.closeStatement(ps);
    -  228  1
             }
    -  229  1
             return data;
    +  224  8
                 DBUtils.closeResultSet(rs);
    +  225  8
                 DBUtils.closeStatement(ps);
    +  226  8
             }
    +  227  8
             return data;
    +  228   +
         }
    +  229   +
     
     230   -
         }
    +
         /**
     231   -
     
    -  232   -
         /**
    -  233  
          * Returns a set of properties.
    -  234   +  232  
          *
    -  235   +  233  
          * @return the properties from the database
    -  236   +  234  
          */
    -  237   +  235  
         Properties getProperties() {
    -  238  3
             final Properties prop = new Properties();
    -  239  3
             PreparedStatement ps = null;
    -  240  3
             ResultSet rs = null;
    -  241   +  236  48
             final Properties prop = new Properties();
    +  237  48
             PreparedStatement ps = null;
    +  238  48
             ResultSet rs = null;
    +  239  
             try {
    -  242  3
                 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_PROPERTIES"));
    -  243  3
                 rs = ps.executeQuery();
    -  244  60
                 while (rs.next()) {
    -  245  57
                     prop.setProperty(rs.getString(1), rs.getString(2));
    -  246   +  240  48
                 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_PROPERTIES"));
    +  241  48
                 rs = ps.executeQuery();
    +  242  960
                 while (rs.next()) {
    +  243  912
                     prop.setProperty(rs.getString(1), rs.getString(2));
    +  244  
                 }
    -  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
                 LOGGER.log(Level.SEVERE, msg);
    -  250  0
                 LOGGER.log(Level.FINE, null, ex);
    -  251   +  245  0
             } catch (SQLException ex) {
    +  246  0
                 LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details.");
    +  247  0
                 LOGGER.debug("", ex);
    +  248  
             } finally {
    -  252  3
                 DBUtils.closeStatement(ps);
    -  253  3
                 DBUtils.closeResultSet(rs);
    -  254  3
             }
    -  255  3
             return prop;
    +  249  48
                 DBUtils.closeStatement(ps);
    +  250  48
                 DBUtils.closeResultSet(rs);
    +  251  48
             }
    +  252  48
             return prop;
    +  253   +
         }
    +  254   +
     
    +  255   +
         /**
     256   -
         }
    -  257   -
     
    -  258   -
         /**
    -  259  
          * Saves a set of properties to the database.
    -  260   +  257  
          *
    -  261   +  258  
          * @param props a collection of properties
    -  262   +  259  
          */
    -  263   +  260  
         void saveProperties(Properties props) {
    -  264  0
             PreparedStatement updateProperty = null;
    -  265  0
             PreparedStatement insertProperty = null;
    -  266   +  261  0
             PreparedStatement updateProperty = null;
    +  262  0
             PreparedStatement insertProperty = null;
    +  263  
             try {
    -  267   +  264  
                 try {
    -  268  0
                     updateProperty = getConnection().prepareStatement(statementBundle.getString("UPDATE_PROPERTY"));
    -  269  0
                     insertProperty = getConnection().prepareStatement(statementBundle.getString("INSERT_PROPERTY"));
    -  270  0
                 } catch (SQLException ex) {
    -  271  0
                     LOGGER.log(Level.WARNING, "Unable to save properties to the database");
    -  272  0
                     LOGGER.log(Level.FINE, "Unable to save properties to the database", ex);
    -  273   +  265  0
                     updateProperty = getConnection().prepareStatement(statementBundle.getString("UPDATE_PROPERTY"));
    +  266  0
                     insertProperty = getConnection().prepareStatement(statementBundle.getString("INSERT_PROPERTY"));
    +  267  0
                 } catch (SQLException ex) {
    +  268  0
                     LOGGER.warn("Unable to save properties to the database");
    +  269  0
                     LOGGER.debug("Unable to save properties to the database", ex);
    +  270  
                     return;
    -  274  0
                 }
    -  275  0
                 for (Entry<Object, Object> entry : props.entrySet()) {
    -  276  0
                     final String key = entry.getKey().toString();
    -  277  0
                     final String value = entry.getValue().toString();
    -  278   +  271  0
                 }
    +  272  0
                 for (Entry<Object, Object> entry : props.entrySet()) {
    +  273  0
                     final String key = entry.getKey().toString();
    +  274  0
                     final String value = entry.getValue().toString();
    +  275  
                     try {
    -  279  0
                         updateProperty.setString(1, value);
    -  280  0
                         updateProperty.setString(2, key);
    -  281  0
                         if (updateProperty.executeUpdate() == 0) {
    -  282  0
                             insertProperty.setString(1, key);
    -  283  0
                             insertProperty.setString(2, value);
    -  284   +  276  0
                         updateProperty.setString(1, value);
    +  277  0
                         updateProperty.setString(2, key);
    +  278  0
                         if (updateProperty.executeUpdate() == 0) {
    +  279  0
                             insertProperty.setString(1, key);
    +  280  0
                             insertProperty.setString(2, value);
    +  281  
                         }
    -  285  0
                     } catch (SQLException ex) {
    -  286  0
                         final String msg = String.format("Unable to save property '%s' with a value of '%s' to the database", key, value);
    -  287  0
                         LOGGER.log(Level.WARNING, msg);
    -  288  0
                         LOGGER.log(Level.FINE, null, ex);
    -  289  0
                     }
    -  290  0
                 }
    -  291   +  282  0
                     } catch (SQLException ex) {
    +  283  0
                         LOGGER.warn("Unable to save property '{}' with a value of '{}' to the database", key, value);
    +  284  0
                         LOGGER.debug("", ex);
    +  285  0
                     }
    +  286  0
                 }
    +  287  
             } finally {
    -  292  0
                 DBUtils.closeStatement(updateProperty);
    -  293  0
                 DBUtils.closeStatement(insertProperty);
    -  294  0
             }
    -  295  0
         }
    -  296   +  288  0
                 DBUtils.closeStatement(updateProperty);
    +  289  0
                 DBUtils.closeStatement(insertProperty);
    +  290  0
             }
    +  291  0
         }
    +  292  
     
    -  297   +  293  
         /**
    -  298   +  294  
          * Saves a property to the database.
    -  299   +  295  
          *
    -  300   +  296  
          * @param key the property key
    -  301   +  297  
          * @param value the property value
    -  302   +  298  
          */
    -  303   +  299  
         void saveProperty(String key, String value) {
    -  304  0
             PreparedStatement updateProperty = null;
    -  305  0
             PreparedStatement insertProperty = null;
    -  306   +  300  0
             PreparedStatement updateProperty = null;
    +  301  0
             PreparedStatement insertProperty = null;
    +  302  
             try {
    -  307   +  303  
                 try {
    -  308  0
                     updateProperty = getConnection().prepareStatement(statementBundle.getString("UPDATE_PROPERTY"));
    -  309  0
                 } catch (SQLException ex) {
    -  310  0
                     LOGGER.log(Level.WARNING, "Unable to save properties to the database");
    -  311  0
                     LOGGER.log(Level.FINE, "Unable to save properties to the database", ex);
    -  312   +  304  0
                     updateProperty = getConnection().prepareStatement(statementBundle.getString("UPDATE_PROPERTY"));
    +  305  0
                 } catch (SQLException ex) {
    +  306  0
                     LOGGER.warn("Unable to save properties to the database");
    +  307  0
                     LOGGER.debug("Unable to save properties to the database", ex);
    +  308  
                     return;
    -  313  0
                 }
    +  309  0
                 }
    +  310   +
                 try {
    +  311  0
                     updateProperty.setString(1, value);
    +  312  0
                     updateProperty.setString(2, key);
    +  313  0
                     if (updateProperty.executeUpdate() == 0) {
     314   -
                 try {
    -  315  0
                     updateProperty.setString(1, value);
    -  316  0
                     updateProperty.setString(2, key);
    -  317  0
                     if (updateProperty.executeUpdate() == 0) {
    -  318  
                         try {
    -  319  0
                             insertProperty = getConnection().prepareStatement(statementBundle.getString("INSERT_PROPERTY"));
    -  320  0
                         } catch (SQLException ex) {
    -  321  0
                             LOGGER.log(Level.WARNING, "Unable to save properties to the database");
    -  322  0
                             LOGGER.log(Level.FINE, "Unable to save properties to the database", ex);
    -  323   +  315  0
                             insertProperty = getConnection().prepareStatement(statementBundle.getString("INSERT_PROPERTY"));
    +  316  0
                         } catch (SQLException ex) {
    +  317  0
                             LOGGER.warn("Unable to save properties to the database");
    +  318  0
                             LOGGER.debug("Unable to save properties to the database", ex);
    +  319  
                             return;
    -  324  0
                         }
    -  325  0
                         insertProperty.setString(1, key);
    -  326  0
                         insertProperty.setString(2, value);
    -  327  0
                         insertProperty.execute();
    -  328   +  320  0
                         }
    +  321  0
                         insertProperty.setString(1, key);
    +  322  0
                         insertProperty.setString(2, value);
    +  323  0
                         insertProperty.execute();
    +  324  
                     }
    -  329  0
                 } catch (SQLException ex) {
    -  330  0
                     final String msg = String.format("Unable to save property '%s' with a value of '%s' to the database", key, value);
    -  331  0
                     LOGGER.log(Level.WARNING, msg);
    -  332  0
                     LOGGER.log(Level.FINE, null, ex);
    -  333  0
                 }
    +  325  0
                 } catch (SQLException ex) {
    +  326  0
                     LOGGER.warn("Unable to save property '{}' with a value of '{}' to the database", key, value);
    +  327  0
                     LOGGER.debug("", ex);
    +  328  0
                 }
    +  329   +
             } finally {
    +  330  0
                 DBUtils.closeStatement(updateProperty);
    +  331  0
                 DBUtils.closeStatement(insertProperty);
    +  332  0
             }
    +  333  0
         }
     334   -
             } finally {
    -  335  0
                 DBUtils.closeStatement(updateProperty);
    -  336  0
                 DBUtils.closeStatement(insertProperty);
    -  337  0
             }
    -  338  0
         }
    -  339  
     
    -  340   +  335  
         /**
    -  341   +  336  
          * Retrieves the vulnerabilities associated with the specified CPE.
    -  342   +  337  
          *
    -  343   +  338  
          * @param cpeStr the CPE name
    -  344   +  339  
          * @return a list of Vulnerabilities
    -  345   +  340  
          * @throws DatabaseException thrown if there is an exception retrieving data
    -  346   +  341  
          */
    -  347   +  342  
         public List<Vulnerability> getVulnerabilities(String cpeStr) throws DatabaseException {
    -  348  2
             ResultSet rs = null;
    -  349  2
             final VulnerableSoftware cpe = new VulnerableSoftware();
    -  350   +  343  24
             ResultSet rs = null;
    +  344  24
             final VulnerableSoftware cpe = new VulnerableSoftware();
    +  345  
             try {
    -  351  2
                 cpe.parseName(cpeStr);
    -  352  0
             } catch (UnsupportedEncodingException ex) {
    -  353  0
                 LOGGER.log(Level.FINEST, null, ex);
    -  354  2
             }
    -  355  2
             final DependencyVersion detectedVersion = parseDependencyVersion(cpe);
    -  356  2
             final List<Vulnerability> vulnerabilities = new ArrayList<Vulnerability>();
    -  357   +  346  24
                 cpe.parseName(cpeStr);
    +  347  0
             } catch (UnsupportedEncodingException ex) {
    +  348  0
                 LOGGER.trace("", ex);
    +  349  24
             }
    +  350  24
             final DependencyVersion detectedVersion = parseDependencyVersion(cpe);
    +  351  24
             final List<Vulnerability> vulnerabilities = new ArrayList<Vulnerability>();
    +  352  
     
    -  358   +  353  
             PreparedStatement ps;
    -  359   +  354  
             try {
    -  360  2
                 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_CVE_FROM_SOFTWARE"));
    -  361  2
                 ps.setString(1, cpe.getVendor());
    -  362  2
                 ps.setString(2, cpe.getProduct());
    -  363  2
                 rs = ps.executeQuery();
    -  364  2
                 String currentCVE = "";
    -  365   +  355  24
                 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_CVE_FROM_SOFTWARE"));
    +  356  24
                 ps.setString(1, cpe.getVendor());
    +  357  24
                 ps.setString(2, cpe.getProduct());
    +  358  24
                 rs = ps.executeQuery();
    +  359  24
                 String currentCVE = "";
    +  360  
     
    -  366  2
                 final Map<String, Boolean> vulnSoftware = new HashMap<String, Boolean>();
    -  367  225
                 while (rs.next()) {
    -  368  223
                     final String cveId = rs.getString(1);
    -  369  223
                     if (!currentCVE.equals(cveId)) { //check for match and add
    -  370  8
                         final Entry<String, Boolean> matchedCPE = getMatchingSoftware(vulnSoftware, cpe.getVendor(), cpe.getProduct(), detectedVersion);
    -  371  8
                         if (matchedCPE != null) {
    -  372  6
                             final Vulnerability v = getVulnerability(currentCVE);
    -  373  6
                             v.setMatchedCPE(matchedCPE.getKey(), matchedCPE.getValue() ? "Y" : null);
    -  374  6
                             vulnerabilities.add(v);
    -  375   +  361  24
                 final Map<String, Boolean> vulnSoftware = new HashMap<String, Boolean>();
    +  362  2256
                 while (rs.next()) {
    +  363  2232
                     final String cveId = rs.getString(1);
    +  364  2232
                     if (!currentCVE.equals(cveId)) { //check for match and add
    +  365  80
                         final Entry<String, Boolean> matchedCPE = getMatchingSoftware(vulnSoftware, cpe.getVendor(), cpe.getProduct(), detectedVersion);
    +  366  80
                         if (matchedCPE != null) {
    +  367  48
                             final Vulnerability v = getVulnerability(currentCVE);
    +  368  48
                             v.setMatchedCPE(matchedCPE.getKey(), matchedCPE.getValue() ? "Y" : null);
    +  369  48
                             vulnerabilities.add(v);
    +  370  
                         }
    -  376  8
                         vulnSoftware.clear();
    -  377  8
                         currentCVE = cveId;
    -  378   +  371  80
                         vulnSoftware.clear();
    +  372  80
                         currentCVE = cveId;
    +  373  
                     }
    -  379   +  374  
     
    -  380  223
                     final String cpeId = rs.getString(2);
    -  381  223
                     final String previous = rs.getString(3);
    -  382  223
                     final Boolean p = previous != null && !previous.isEmpty();
    -  383  223
                     vulnSoftware.put(cpeId, p);
    -  384  223
                 }
    -  385   +  375  2232
                     final String cpeId = rs.getString(2);
    +  376  2232
                     final String previous = rs.getString(3);
    +  377  2232
                     final Boolean p = previous != null && !previous.isEmpty();
    +  378  2232
                     vulnSoftware.put(cpeId, p);
    +  379  2232
                 }
    +  380  
                 //remember to process the last set of CVE/CPE entries
    -  386  2
                 final Entry<String, Boolean> matchedCPE = getMatchingSoftware(vulnSoftware, cpe.getVendor(), cpe.getProduct(), detectedVersion);
    -  387  2
                 if (matchedCPE != null) {
    -  388  2
                     final Vulnerability v = getVulnerability(currentCVE);
    -  389  2
                     v.setMatchedCPE(matchedCPE.getKey(), matchedCPE.getValue() ? "Y" : null);
    -  390  2
                     vulnerabilities.add(v);
    +  381  24
                 final Entry<String, Boolean> matchedCPE = getMatchingSoftware(vulnSoftware, cpe.getVendor(), cpe.getProduct(), detectedVersion);
    +  382  24
                 if (matchedCPE != null) {
    +  383  16
                     final Vulnerability v = getVulnerability(currentCVE);
    +  384  16
                     v.setMatchedCPE(matchedCPE.getKey(), matchedCPE.getValue() ? "Y" : null);
    +  385  16
                     vulnerabilities.add(v);
    +  386   +
                 }
    +  387  24
                 DBUtils.closeResultSet(rs);
    +  388  24
                 DBUtils.closeStatement(ps);
    +  389  0
             } catch (SQLException ex) {
    +  390  0
                 throw new DatabaseException("Exception retrieving vulnerability for " + cpeStr, ex);
     391   -
                 }
    -  392  2
                 DBUtils.closeResultSet(rs);
    -  393  2
                 DBUtils.closeStatement(ps);
    -  394  0
             } catch (SQLException ex) {
    -  395  0
                 throw new DatabaseException("Exception retrieving vulnerability for " + cpeStr, ex);
    +
             } finally {
    +  392  24
                 DBUtils.closeResultSet(rs);
    +  393  24
             }
    +  394  24
             return vulnerabilities;
    +  395   +
         }
     396   -
             } finally {
    -  397  2
                 DBUtils.closeResultSet(rs);
    -  398  2
             }
    -  399  2
             return vulnerabilities;
    -  400   -
         }
    -  401  
     
    -  402   +  397  
         /**
    -  403   +  398  
          * Gets a vulnerability for the provided CVE.
    -  404   +  399  
          *
    -  405   +  400  
          * @param cve the CVE to lookup
    -  406   +  401  
          * @return a vulnerability object
    -  407   +  402  
          * @throws DatabaseException if an exception occurs
    -  408   +  403  
          */
    -  409   +  404  
         private Vulnerability getVulnerability(String cve) throws DatabaseException {
    -  410  8
             PreparedStatement psV = null;
    -  411  8
             PreparedStatement psR = null;
    -  412  8
             PreparedStatement psS = null;
    -  413  8
             ResultSet rsV = null;
    -  414  8
             ResultSet rsR = null;
    -  415  8
             ResultSet rsS = null;
    -  416  8
             Vulnerability vuln = null;
    -  417   +  405  64
             PreparedStatement psV = null;
    +  406  64
             PreparedStatement psR = null;
    +  407  64
             PreparedStatement psS = null;
    +  408  64
             ResultSet rsV = null;
    +  409  64
             ResultSet rsR = null;
    +  410  64
             ResultSet rsS = null;
    +  411  64
             Vulnerability vuln = null;
    +  412  
             try {
    -  418  8
                 psV = getConnection().prepareStatement(statementBundle.getString("SELECT_VULNERABILITY"));
    -  419  8
                 psV.setString(1, cve);
    -  420  8
                 rsV = psV.executeQuery();
    -  421  8
                 if (rsV.next()) {
    -  422  8
                     vuln = new Vulnerability();
    -  423  8
                     vuln.setName(cve);
    -  424  8
                     vuln.setDescription(rsV.getString(2));
    -  425  8
                     String cwe = rsV.getString(3);
    -  426  8
                     if (cwe != null) {
    -  427  8
                         final String name = CweDB.getCweName(cwe);
    -  428  8
                         if (name != null) {
    -  429  7
                             cwe += " " + name;
    -  430   +  413  64
                 psV = getConnection().prepareStatement(statementBundle.getString("SELECT_VULNERABILITY"));
    +  414  64
                 psV.setString(1, cve);
    +  415  64
                 rsV = psV.executeQuery();
    +  416  64
                 if (rsV.next()) {
    +  417  64
                     vuln = new Vulnerability();
    +  418  64
                     vuln.setName(cve);
    +  419  64
                     vuln.setDescription(rsV.getString(2));
    +  420  64
                     String cwe = rsV.getString(3);
    +  421  64
                     if (cwe != null) {
    +  422  64
                         final String name = CweDB.getCweName(cwe);
    +  423  64
                         if (name != null) {
    +  424  56
                             cwe += " " + name;
    +  425  
                         }
    -  431   +  426  
                     }
    -  432  8
                     final int cveId = rsV.getInt(1);
    -  433  8
                     vuln.setCwe(cwe);
    -  434  8
                     vuln.setCvssScore(rsV.getFloat(4));
    -  435  8
                     vuln.setCvssAccessVector(rsV.getString(5));
    -  436  8
                     vuln.setCvssAccessComplexity(rsV.getString(6));
    -  437  8
                     vuln.setCvssAuthentication(rsV.getString(7));
    -  438  8
                     vuln.setCvssConfidentialityImpact(rsV.getString(8));
    -  439  8
                     vuln.setCvssIntegrityImpact(rsV.getString(9));
    -  440  8
                     vuln.setCvssAvailabilityImpact(rsV.getString(10));
    -  441   +  427  64
                     final int cveId = rsV.getInt(1);
    +  428  64
                     vuln.setCwe(cwe);
    +  429  64
                     vuln.setCvssScore(rsV.getFloat(4));
    +  430  64
                     vuln.setCvssAccessVector(rsV.getString(5));
    +  431  64
                     vuln.setCvssAccessComplexity(rsV.getString(6));
    +  432  64
                     vuln.setCvssAuthentication(rsV.getString(7));
    +  433  64
                     vuln.setCvssConfidentialityImpact(rsV.getString(8));
    +  434  64
                     vuln.setCvssIntegrityImpact(rsV.getString(9));
    +  435  64
                     vuln.setCvssAvailabilityImpact(rsV.getString(10));
    +  436  
     
    -  442  8
                     psR = getConnection().prepareStatement(statementBundle.getString("SELECT_REFERENCES"));
    -  443  8
                     psR.setInt(1, cveId);
    -  444  8
                     rsR = psR.executeQuery();
    -  445  74
                     while (rsR.next()) {
    -  446  66
                         vuln.addReference(rsR.getString(1), rsR.getString(2), rsR.getString(3));
    -  447   +  437  64
                     psR = getConnection().prepareStatement(statementBundle.getString("SELECT_REFERENCES"));
    +  438  64
                     psR.setInt(1, cveId);
    +  439  64
                     rsR = psR.executeQuery();
    +  440  608
                     while (rsR.next()) {
    +  441  544
                         vuln.addReference(rsR.getString(1), rsR.getString(2), rsR.getString(3));
    +  442  
                     }
    -  448  8
                     psS = getConnection().prepareStatement(statementBundle.getString("SELECT_SOFTWARE"));
    -  449  8
                     psS.setInt(1, cveId);
    -  450  8
                     rsS = psS.executeQuery();
    -  451  244
                     while (rsS.next()) {
    -  452  236
                         final String cpe = rsS.getString(1);
    -  453  236
                         final String prevVersion = rsS.getString(2);
    -  454  236
                         if (prevVersion == null) {
    -  455  228
                             vuln.addVulnerableSoftware(cpe);
    -  456   +  443  64
                     psS = getConnection().prepareStatement(statementBundle.getString("SELECT_SOFTWARE"));
    +  444  64
                     psS.setInt(1, cveId);
    +  445  64
                     rsS = psS.executeQuery();
    +  446  1952
                     while (rsS.next()) {
    +  447  1888
                         final String cpe = rsS.getString(1);
    +  448  1888
                         final String prevVersion = rsS.getString(2);
    +  449  1888
                         if (prevVersion == null) {
    +  450  1824
                             vuln.addVulnerableSoftware(cpe);
    +  451  
                         } else {
    -  457  8
                             vuln.addVulnerableSoftware(cpe, prevVersion);
    +  452  64
                             vuln.addVulnerableSoftware(cpe, prevVersion);
    +  453   +
                         }
    +  454  1888
                     }
    +  455   +
                 }
    +  456  0
             } catch (SQLException ex) {
    +  457  0
                 throw new DatabaseException("Error retrieving " + cve, ex);
     458   -
                         }
    -  459  236
                     }
    -  460   -
                 }
    -  461  0
             } catch (SQLException ex) {
    -  462  0
                 throw new DatabaseException("Error retrieving " + cve, ex);
    -  463  
             } finally {
    -  464  8
                 DBUtils.closeResultSet(rsV);
    -  465  8
                 DBUtils.closeResultSet(rsR);
    -  466  8
                 DBUtils.closeResultSet(rsS);
    -  467  8
                 DBUtils.closeStatement(psV);
    -  468  8
                 DBUtils.closeStatement(psR);
    -  469  8
                 DBUtils.closeStatement(psS);
    -  470  8
             }
    -  471  8
             return vuln;
    -  472   +  459  64
                 DBUtils.closeResultSet(rsV);
    +  460  64
                 DBUtils.closeResultSet(rsR);
    +  461  64
                 DBUtils.closeResultSet(rsS);
    +  462  64
                 DBUtils.closeStatement(psV);
    +  463  64
                 DBUtils.closeStatement(psR);
    +  464  64
                 DBUtils.closeStatement(psS);
    +  465  64
             }
    +  466  64
             return vuln;
    +  467  
         }
    -  473   +  468  
     
    -  474   +  469  
         /**
    -  475   +  470  
          * Updates the vulnerability within the database. If the vulnerability does not exist it will be added.
    -  476   +  471  
          *
    -  477   +  472  
          * @param vuln the vulnerability to add to the database
    -  478   +  473  
          * @throws DatabaseException is thrown if the database
    -  479   +  474  
          */
    -  480   +  475  
         public void updateVulnerability(Vulnerability vuln) throws DatabaseException {
    -  481  0
             PreparedStatement selectVulnerabilityId = null;
    -  482  0
             PreparedStatement deleteVulnerability = null;
    -  483  0
             PreparedStatement deleteReferences = null;
    -  484  0
             PreparedStatement deleteSoftware = null;
    -  485  0
             PreparedStatement updateVulnerability = null;
    -  486  0
             PreparedStatement insertVulnerability = null;
    -  487  0
             PreparedStatement insertReference = null;
    -  488  0
             PreparedStatement selectCpeId = null;
    -  489  0
             PreparedStatement insertCpe = null;
    -  490  0
             PreparedStatement insertSoftware = null;
    -  491   +  476  0
             PreparedStatement selectVulnerabilityId = null;
    +  477  0
             PreparedStatement deleteVulnerability = null;
    +  478  0
             PreparedStatement deleteReferences = null;
    +  479  0
             PreparedStatement deleteSoftware = null;
    +  480  0
             PreparedStatement updateVulnerability = null;
    +  481  0
             PreparedStatement insertVulnerability = null;
    +  482  0
             PreparedStatement insertReference = null;
    +  483  0
             PreparedStatement selectCpeId = null;
    +  484  0
             PreparedStatement insertCpe = null;
    +  485  0
             PreparedStatement insertSoftware = null;
    +  486  
     
    -  492   +  487  
             try {
    -  493  0
                 selectVulnerabilityId = getConnection().prepareStatement(statementBundle.getString("SELECT_VULNERABILITY_ID"));
    -  494  0
                 deleteVulnerability = getConnection().prepareStatement(statementBundle.getString("DELETE_VULNERABILITY"));
    -  495  0
                 deleteReferences = getConnection().prepareStatement(statementBundle.getString("DELETE_REFERENCE"));
    -  496  0
                 deleteSoftware = getConnection().prepareStatement(statementBundle.getString("DELETE_SOFTWARE"));
    -  497  0
                 updateVulnerability = getConnection().prepareStatement(statementBundle.getString("UPDATE_VULNERABILITY"));
    -  498  0
                 insertVulnerability = getConnection().prepareStatement(statementBundle.getString("INSERT_VULNERABILITY"),
    -  499   -
                         Statement.RETURN_GENERATED_KEYS);
    -  500  0
                 insertReference = getConnection().prepareStatement(statementBundle.getString("INSERT_REFERENCE"));
    -  501  0
                 selectCpeId = getConnection().prepareStatement(statementBundle.getString("SELECT_CPE_ID"));
    -  502  0
                 insertCpe = getConnection().prepareStatement(statementBundle.getString("INSERT_CPE"),
    -  503   -
                         Statement.RETURN_GENERATED_KEYS);
    -  504  0
                 insertSoftware = getConnection().prepareStatement(statementBundle.getString("INSERT_SOFTWARE"));
    -  505  0
                 int vulnerabilityId = 0;
    -  506  0
                 selectVulnerabilityId.setString(1, vuln.getName());
    -  507  0
                 ResultSet rs = selectVulnerabilityId.executeQuery();
    -  508  0
                 if (rs.next()) {
    -  509  0
                     vulnerabilityId = rs.getInt(1);
    -  510   +  488  0
                 selectVulnerabilityId = getConnection().prepareStatement(statementBundle.getString("SELECT_VULNERABILITY_ID"));
    +  489  0
                 deleteVulnerability = getConnection().prepareStatement(statementBundle.getString("DELETE_VULNERABILITY"));
    +  490  0
                 deleteReferences = getConnection().prepareStatement(statementBundle.getString("DELETE_REFERENCE"));
    +  491  0
                 deleteSoftware = getConnection().prepareStatement(statementBundle.getString("DELETE_SOFTWARE"));
    +  492  0
                 updateVulnerability = getConnection().prepareStatement(statementBundle.getString("UPDATE_VULNERABILITY"));
    +  493  0
                 String ids[] = {"id"};
    +  494  0
                 insertVulnerability = getConnection().prepareStatement(statementBundle.getString("INSERT_VULNERABILITY"),
    +  495   +
                         //Statement.RETURN_GENERATED_KEYS);
    +  496   +
                         ids);
    +  497  0
                 insertReference = getConnection().prepareStatement(statementBundle.getString("INSERT_REFERENCE"));
    +  498  0
                 selectCpeId = getConnection().prepareStatement(statementBundle.getString("SELECT_CPE_ID"));
    +  499  0
                 insertCpe = getConnection().prepareStatement(statementBundle.getString("INSERT_CPE"),
    +  500   +
                         //Statement.RETURN_GENERATED_KEYS);
    +  501   +
                         ids);
    +  502  0
                 insertSoftware = getConnection().prepareStatement(statementBundle.getString("INSERT_SOFTWARE"));
    +  503  0
                 int vulnerabilityId = 0;
    +  504  0
                 selectVulnerabilityId.setString(1, vuln.getName());
    +  505  0
                 ResultSet rs = selectVulnerabilityId.executeQuery();
    +  506  0
                 if (rs.next()) {
    +  507  0
                     vulnerabilityId = rs.getInt(1);
    +  508  
                     // first delete any existing vulnerability info. We don't know what was updated. yes, slower but atm easier.
    -  511  0
                     deleteReferences.setInt(1, vulnerabilityId);
    -  512  0
                     deleteReferences.execute();
    -  513  0
                     deleteSoftware.setInt(1, vulnerabilityId);
    -  514  0
                     deleteSoftware.execute();
    -  515   +  509  0
                     deleteReferences.setInt(1, vulnerabilityId);
    +  510  0
                     deleteReferences.execute();
    +  511  0
                     deleteSoftware.setInt(1, vulnerabilityId);
    +  512  0
                     deleteSoftware.execute();
    +  513  
                 }
    -  516  0
                 DBUtils.closeResultSet(rs);
    -  517  0
                 rs = null;
    -  518  0
                 if (vulnerabilityId != 0) {
    -  519  0
                     if (vuln.getDescription().contains("** REJECT **")) {
    -  520  0
                         deleteVulnerability.setInt(1, vulnerabilityId);
    -  521  0
                         deleteVulnerability.executeUpdate();
    -  522   +  514  0
                 DBUtils.closeResultSet(rs);
    +  515  0
                 rs = null;
    +  516  0
                 if (vulnerabilityId != 0) {
    +  517  0
                     if (vuln.getDescription().contains("** REJECT **")) {
    +  518  0
                         deleteVulnerability.setInt(1, vulnerabilityId);
    +  519  0
                         deleteVulnerability.executeUpdate();
    +  520  
                     } else {
    -  523  0
                         updateVulnerability.setString(1, vuln.getDescription());
    -  524  0
                         updateVulnerability.setString(2, vuln.getCwe());
    -  525  0
                         updateVulnerability.setFloat(3, vuln.getCvssScore());
    -  526  0
                         updateVulnerability.setString(4, vuln.getCvssAccessVector());
    -  527  0
                         updateVulnerability.setString(5, vuln.getCvssAccessComplexity());
    -  528  0
                         updateVulnerability.setString(6, vuln.getCvssAuthentication());
    -  529  0
                         updateVulnerability.setString(7, vuln.getCvssConfidentialityImpact());
    -  530  0
                         updateVulnerability.setString(8, vuln.getCvssIntegrityImpact());
    -  531  0
                         updateVulnerability.setString(9, vuln.getCvssAvailabilityImpact());
    -  532  0
                         updateVulnerability.setInt(10, vulnerabilityId);
    -  533  0
                         updateVulnerability.executeUpdate();
    -  534   +  521  0
                         updateVulnerability.setString(1, vuln.getDescription());
    +  522  0
                         updateVulnerability.setString(2, vuln.getCwe());
    +  523  0
                         updateVulnerability.setFloat(3, vuln.getCvssScore());
    +  524  0
                         updateVulnerability.setString(4, vuln.getCvssAccessVector());
    +  525  0
                         updateVulnerability.setString(5, vuln.getCvssAccessComplexity());
    +  526  0
                         updateVulnerability.setString(6, vuln.getCvssAuthentication());
    +  527  0
                         updateVulnerability.setString(7, vuln.getCvssConfidentialityImpact());
    +  528  0
                         updateVulnerability.setString(8, vuln.getCvssIntegrityImpact());
    +  529  0
                         updateVulnerability.setString(9, vuln.getCvssAvailabilityImpact());
    +  530  0
                         updateVulnerability.setInt(10, vulnerabilityId);
    +  531  0
                         updateVulnerability.executeUpdate();
    +  532  
                     }
    -  535   +  533  
                 } else {
    -  536  0
                     insertVulnerability.setString(1, vuln.getName());
    -  537  0
                     insertVulnerability.setString(2, vuln.getDescription());
    -  538  0
                     insertVulnerability.setString(3, vuln.getCwe());
    -  539  0
                     insertVulnerability.setFloat(4, vuln.getCvssScore());
    -  540  0
                     insertVulnerability.setString(5, vuln.getCvssAccessVector());
    -  541  0
                     insertVulnerability.setString(6, vuln.getCvssAccessComplexity());
    -  542  0
                     insertVulnerability.setString(7, vuln.getCvssAuthentication());
    -  543  0
                     insertVulnerability.setString(8, vuln.getCvssConfidentialityImpact());
    -  544  0
                     insertVulnerability.setString(9, vuln.getCvssIntegrityImpact());
    -  545  0
                     insertVulnerability.setString(10, vuln.getCvssAvailabilityImpact());
    -  546  0
                     insertVulnerability.execute();
    -  547   +  534  0
                     insertVulnerability.setString(1, vuln.getName());
    +  535  0
                     insertVulnerability.setString(2, vuln.getDescription());
    +  536  0
                     insertVulnerability.setString(3, vuln.getCwe());
    +  537  0
                     insertVulnerability.setFloat(4, vuln.getCvssScore());
    +  538  0
                     insertVulnerability.setString(5, vuln.getCvssAccessVector());
    +  539  0
                     insertVulnerability.setString(6, vuln.getCvssAccessComplexity());
    +  540  0
                     insertVulnerability.setString(7, vuln.getCvssAuthentication());
    +  541  0
                     insertVulnerability.setString(8, vuln.getCvssConfidentialityImpact());
    +  542  0
                     insertVulnerability.setString(9, vuln.getCvssIntegrityImpact());
    +  543  0
                     insertVulnerability.setString(10, vuln.getCvssAvailabilityImpact());
    +  544  0
                     insertVulnerability.execute();
    +  545  
                     try {
    -  548  0
                         rs = insertVulnerability.getGeneratedKeys();
    -  549  0
                         rs.next();
    -  550  0
                         vulnerabilityId = rs.getInt(1);
    -  551  0
                     } catch (SQLException ex) {
    -  552  0
                         final String msg = String.format("Unable to retrieve id for new vulnerability for '%s'", vuln.getName());
    -  553  0
                         throw new DatabaseException(msg, ex);
    -  554   +  546  0
                         rs = insertVulnerability.getGeneratedKeys();
    +  547  0
                         rs.next();
    +  548  0
                         vulnerabilityId = rs.getInt(1);
    +  549  0
                     } catch (SQLException ex) {
    +  550  0
                         final String msg = String.format("Unable to retrieve id for new vulnerability for '%s'", vuln.getName());
    +  551  0
                         throw new DatabaseException(msg, ex);
    +  552  
                     } finally {
    -  555  0
                         DBUtils.closeResultSet(rs);
    -  556  0
                         rs = null;
    -  557  0
                     }
    -  558   +  553  0
                         DBUtils.closeResultSet(rs);
    +  554  0
                         rs = null;
    +  555  0
                     }
    +  556  
                 }
    -  559  0
                 insertReference.setInt(1, vulnerabilityId);
    -  560  0
                 for (Reference r : vuln.getReferences()) {
    -  561  0
                     insertReference.setString(2, r.getName());
    -  562  0
                     insertReference.setString(3, r.getUrl());
    -  563  0
                     insertReference.setString(4, r.getSource());
    -  564  0
                     insertReference.execute();
    -  565  0
                 }
    -  566  0
                 for (VulnerableSoftware s : vuln.getVulnerableSoftware()) {
    -  567  0
                     int cpeProductId = 0;
    -  568  0
                     selectCpeId.setString(1, s.getName());
    -  569   +  557  0
                 insertReference.setInt(1, vulnerabilityId);
    +  558  0
                 for (Reference r : vuln.getReferences()) {
    +  559  0
                     insertReference.setString(2, r.getName());
    +  560  0
                     insertReference.setString(3, r.getUrl());
    +  561  0
                     insertReference.setString(4, r.getSource());
    +  562  0
                     insertReference.execute();
    +  563  0
                 }
    +  564  0
                 for (VulnerableSoftware s : vuln.getVulnerableSoftware()) {
    +  565  0
                     int cpeProductId = 0;
    +  566  0
                     selectCpeId.setString(1, s.getName());
    +  567  
                     try {
    -  570  0
                         rs = selectCpeId.executeQuery();
    -  571  0
                         if (rs.next()) {
    -  572  0
                             cpeProductId = rs.getInt(1);
    -  573   +  568  0
                         rs = selectCpeId.executeQuery();
    +  569  0
                         if (rs.next()) {
    +  570  0
                             cpeProductId = rs.getInt(1);
    +  571  
                         }
    -  574  0
                     } catch (SQLException ex) {
    -  575  0
                         throw new DatabaseException("Unable to get primary key for new cpe: " + s.getName(), ex);
    -  576   +  572  0
                     } catch (SQLException ex) {
    +  573  0
                         throw new DatabaseException("Unable to get primary key for new cpe: " + s.getName(), ex);
    +  574  
                     } finally {
    -  577  0
                         DBUtils.closeResultSet(rs);
    -  578  0
                         rs = null;
    -  579  0
                     }
    -  580   +  575  0
                         DBUtils.closeResultSet(rs);
    +  576  0
                         rs = null;
    +  577  0
                     }
    +  578  
     
    -  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   +  579  0
                     if (cpeProductId == 0) {
    +  580  0
                         insertCpe.setString(1, s.getName());
    +  581  0
                         insertCpe.setString(2, s.getVendor());
    +  582  0
                         insertCpe.setString(3, s.getProduct());
    +  583  0
                         insertCpe.executeUpdate();
    +  584  0
                         cpeProductId = DBUtils.getGeneratedKey(insertCpe);
    +  585  
                     }
    -  588  0
                     if (cpeProductId == 0) {
    -  589  0
                         throw new DatabaseException("Unable to retrieve cpeProductId - no data returned");
    -  590   +  586  0
                     if (cpeProductId == 0) {
    +  587  0
                         throw new DatabaseException("Unable to retrieve cpeProductId - no data returned");
    +  588  
                     }
    -  591   +  589  
     
    -  592  0
                     insertSoftware.setInt(1, vulnerabilityId);
    -  593  0
                     insertSoftware.setInt(2, cpeProductId);
    -  594  0
                     if (s.getPreviousVersion() == null) {
    -  595  0
                         insertSoftware.setNull(3, java.sql.Types.VARCHAR);
    +  590  0
                     insertSoftware.setInt(1, vulnerabilityId);
    +  591  0
                     insertSoftware.setInt(2, cpeProductId);
    +  592  0
                     if (s.getPreviousVersion() == null) {
    +  593  0
                         insertSoftware.setNull(3, java.sql.Types.VARCHAR);
    +  594   +
                     } else {
    +  595  0
                         insertSoftware.setString(3, s.getPreviousVersion());
     596   -
                     } else {
    -  597  0
                         insertSoftware.setString(3, s.getPreviousVersion());
    -  598  
                     }
    -  599  0
                     insertSoftware.execute();
    -  600  0
                 }
    -  601   +  597  0
                     insertSoftware.execute();
    +  598  0
                 }
    +  599  
     
    -  602  0
             } catch (SQLException ex) {
    -  603  0
                 final String msg = String.format("Error updating '%s'", vuln.getName());
    -  604  0
                 LOGGER.log(Level.FINE, null, ex);
    -  605  0
                 throw new DatabaseException(msg, ex);
    -  606   +  600  0
             } catch (SQLException ex) {
    +  601  0
                 final String msg = String.format("Error updating '%s'", vuln.getName());
    +  602  0
                 LOGGER.debug("", ex);
    +  603  0
                 throw new DatabaseException(msg, ex);
    +  604  
             } finally {
    -  607  0
                 DBUtils.closeStatement(selectVulnerabilityId);
    -  608  0
                 DBUtils.closeStatement(deleteReferences);
    -  609  0
                 DBUtils.closeStatement(deleteSoftware);
    -  610  0
                 DBUtils.closeStatement(updateVulnerability);
    -  611  0
                 DBUtils.closeStatement(deleteVulnerability);
    -  612  0
                 DBUtils.closeStatement(insertVulnerability);
    -  613  0
                 DBUtils.closeStatement(insertReference);
    -  614  0
                 DBUtils.closeStatement(selectCpeId);
    -  615  0
                 DBUtils.closeStatement(insertCpe);
    -  616  0
                 DBUtils.closeStatement(insertSoftware);
    -  617  0
             }
    -  618  0
         }
    +  605  0
                 DBUtils.closeStatement(selectVulnerabilityId);
    +  606  0
                 DBUtils.closeStatement(deleteReferences);
    +  607  0
                 DBUtils.closeStatement(deleteSoftware);
    +  608  0
                 DBUtils.closeStatement(updateVulnerability);
    +  609  0
                 DBUtils.closeStatement(deleteVulnerability);
    +  610  0
                 DBUtils.closeStatement(insertVulnerability);
    +  611  0
                 DBUtils.closeStatement(insertReference);
    +  612  0
                 DBUtils.closeStatement(selectCpeId);
    +  613  0
                 DBUtils.closeStatement(insertCpe);
    +  614  0
                 DBUtils.closeStatement(insertSoftware);
    +  615  0
             }
    +  616  0
         }
    +  617   +
     
    +  618   +
         /**
     619   -
     
    -  620   -
         /**
    -  621  
          * Checks to see if data exists so that analysis can be performed.
    -  622   +  620  
          *
    -  623   +  621  
          * @return <code>true</code> if data exists; otherwise <code>false</code>
    -  624   +  622  
          */
    -  625   +  623  
         public boolean dataExists() {
    -  626  1
             Statement cs = null;
    -  627  1
             ResultSet rs = null;
    -  628   +  624  8
             Statement cs = null;
    +  625  8
             ResultSet rs = null;
    +  626  
             try {
    -  629  1
                 cs = conn.createStatement();
    -  630  1
                 rs = cs.executeQuery("SELECT COUNT(*) records FROM cpeEntry");
    -  631  1
                 if (rs.next()) {
    -  632  1
                     if (rs.getInt(1) > 0) {
    -  633  1
                         return true;
    -  634   +  627  8
                 cs = conn.createStatement();
    +  628  8
                 rs = cs.executeQuery("SELECT COUNT(*) records FROM cpeEntry");
    +  629  8
                 if (rs.next()) {
    +  630  8
                     if (rs.getInt(1) > 0) {
    +  631  8
                         return true;
    +  632  
                     }
    +  633   +
                 }
    +  634  0
             } catch (SQLException ex) {
     635   -
                 }
    -  636  0
             } catch (SQLException ex) {
    -  637  
                 String dd;
    -  638   +  636  
                 try {
    -  639  0
                     dd = Settings.getDataDirectory().getAbsolutePath();
    -  640  0
                 } catch (IOException ex1) {
    -  641  0
                     dd = Settings.getString(Settings.KEYS.DATA_DIRECTORY);
    -  642  0
                 }
    -  643  0
                 final String msg = String.format("Unable to access the local database.%n%nEnsure that '%s' is a writable directory. "
    -  644   -
                         + "If the problem persist try deleting the files in '%s' and running %s again. If the problem continues, please "
    -  645   +  637  0
                     dd = Settings.getDataDirectory().getAbsolutePath();
    +  638  0
                 } catch (IOException ex1) {
    +  639  0
                     dd = Settings.getString(Settings.KEYS.DATA_DIRECTORY);
    +  640  0
                 }
    +  641  0
                 LOGGER.error("Unable to access the local database.\n\nEnsure that '{}' is a writable directory. "
    +  642   +
                         + "If the problem persist try deleting the files in '{}' and running {} again. If the problem continues, please "
    +  643  
                         + "create a log file (see documentation at http://jeremylong.github.io/DependencyCheck/) and open a ticket at "
    -  646   -
                         + "https://github.com/jeremylong/DependencyCheck/issues and include the log file.%n%n",
    -  647   +  644   +
                         + "https://github.com/jeremylong/DependencyCheck/issues and include the log file.\n\n",
    +  645  
                         dd, dd, Settings.getString(Settings.KEYS.APPLICATION_VAME));
    -  648  0
                 LOGGER.log(Level.SEVERE, msg);
    -  649  0
                 LOGGER.log(Level.FINE, "", ex);
    -  650   +  646  0
                 LOGGER.debug("", ex);
    +  647  
             } finally {
    -  651  1
                 DBUtils.closeResultSet(rs);
    -  652  1
                 DBUtils.closeStatement(cs);
    -  653  0
             }
    -  654  0
             return false;
    +  648  8
                 DBUtils.closeResultSet(rs);
    +  649  8
                 DBUtils.closeStatement(cs);
    +  650  0
             }
    +  651  0
             return false;
    +  652   +
         }
    +  653   +
     
    +  654   +
         /**
     655   -
         }
    -  656   -
     
    -  657   -
         /**
    -  658  
          * It is possible that orphaned rows may be generated during database updates. This should be called after all updates have
    -  659   +  656  
          * been completed to ensure orphan entries are removed.
    -  660   +  657  
          */
    -  661   +  658  
         public void cleanupDatabase() {
    -  662  0
             PreparedStatement ps = null;
    -  663   +  659  0
             PreparedStatement ps = null;
    +  660  
             try {
    -  664  0
                 ps = getConnection().prepareStatement(statementBundle.getString("CLEANUP_ORPHANS"));
    -  665  0
                 if (ps != null) {
    -  666  0
                     ps.executeUpdate();
    -  667   +  661  0
                 ps = getConnection().prepareStatement(statementBundle.getString("CLEANUP_ORPHANS"));
    +  662  0
                 if (ps != null) {
    +  663  0
                     ps.executeUpdate();
    +  664  
                 }
    -  668  0
             } catch (SQLException ex) {
    -  669  0
                 final String msg = "An unexpected SQL Exception occurred; please see the verbose log for more details.";
    -  670  0
                 LOGGER.log(Level.SEVERE, msg);
    -  671  0
                 LOGGER.log(Level.FINE, null, ex);
    -  672   +  665  0
             } catch (SQLException ex) {
    +  666  0
                 LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details.");
    +  667  0
                 LOGGER.debug("", ex);
    +  668  
             } finally {
    -  673  0
                 DBUtils.closeStatement(ps);
    -  674  0
             }
    -  675  0
         }
    -  676   +  669  0
                 DBUtils.closeStatement(ps);
    +  670  0
             }
    +  671  0
         }
    +  672  
     
    -  677   +  673  
         /**
    -  678   +  674  
          * Determines if the given identifiedVersion is affected by the given cpeId and previous version flag. A non-null, non-empty
    -  679   +  675  
          * string passed to the previous version argument indicates that all previous versions are affected.
    -  680   +  676  
          *
    -  681   +  677  
          * @param vendor the vendor of the dependency being analyzed
    -  682   +  678  
          * @param product the product name of the dependency being analyzed
    -  683   +  679  
          * @param vulnerableSoftware a map of the vulnerable software with a boolean indicating if all previous versions are affected
    -  684   +  680  
          * @param identifiedVersion the identified version of the dependency being analyzed
    -  685   +  681  
          * @return true if the identified version is affected, otherwise false
    -  686   +  682  
          */
    -  687   +  683  
         Entry<String, Boolean> getMatchingSoftware(Map<String, Boolean> vulnerableSoftware, String vendor, String product,
    -  688   +  684  
                 DependencyVersion identifiedVersion) {
    -  689   +  685  
     
    -  690  10
             final boolean isVersionTwoADifferentProduct = "apache".equals(vendor) && "struts".equals(product);
    -  691   +  686  104
             final boolean isVersionTwoADifferentProduct = "apache".equals(vendor) && "struts".equals(product);
    +  687  
     
    -  692  10
             final Set<String> majorVersionsAffectingAllPrevious = new HashSet<String>();
    -  693  10
             final boolean matchesAnyPrevious = identifiedVersion == null || "-".equals(identifiedVersion.toString());
    -  694  10
             String majorVersionMatch = null;
    -  695  10
             for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) {
    -  696  223
                 final DependencyVersion v = parseDependencyVersion(entry.getKey());
    -  697  223
                 if (v == null || "-".equals(v.toString())) { //all versions
    -  698  0
                     return entry;
    +  688  104
             final Set<String> majorVersionsAffectingAllPrevious = new HashSet<String>();
    +  689  104
             final boolean matchesAnyPrevious = identifiedVersion == null || "-".equals(identifiedVersion.toString());
    +  690  104
             String majorVersionMatch = null;
    +  691  104
             for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) {
    +  692  2232
                 final DependencyVersion v = parseDependencyVersion(entry.getKey());
    +  693  2232
                 if (v == null || "-".equals(v.toString())) { //all versions
    +  694  0
                     return entry;
    +  695   +
                 }
    +  696  2232
                 if (entry.getValue()) {
    +  697  64
                     if (matchesAnyPrevious) {
    +  698  0
                         return entry;
     699   +
                     }
    +  700  64
                     if (identifiedVersion != null && identifiedVersion.getVersionParts().get(0).equals(v.getVersionParts().get(0))) {
    +  701  48
                         majorVersionMatch = v.getVersionParts().get(0);
    +  702   +
                     }
    +  703  64
                     majorVersionsAffectingAllPrevious.add(v.getVersionParts().get(0));
    +  704  
                 }
    -  700  223
                 if (entry.getValue()) {
    -  701  8
                     if (matchesAnyPrevious) {
    -  702  0
                         return entry;
    -  703   -
                     }
    -  704  8
                     if (identifiedVersion != null && identifiedVersion.getVersionParts().get(0).equals(v.getVersionParts().get(0))) {
    -  705  6
                         majorVersionMatch = v.getVersionParts().get(0);
    -  706   -
                     }
    -  707  8
                     majorVersionsAffectingAllPrevious.add(v.getVersionParts().get(0));
    +  705  2232
             }
    +  706  104
             if (matchesAnyPrevious) {
    +  707  0
                 return null;
     708   -
                 }
    -  709  223
             }
    -  710  10
             if (matchesAnyPrevious) {
    -  711  0
                 return null;
    -  712  
             }
    -  713   +  709  
     
    -  714  10
             final boolean canSkipVersions = majorVersionMatch != null && majorVersionsAffectingAllPrevious.size() > 1;
    -  715   +  710  104
             final boolean canSkipVersions = majorVersionMatch != null && majorVersionsAffectingAllPrevious.size() > 1;
    +  711  
             //yes, we are iterating over this twice. The first time we are skipping versions those that affect all versions
    -  716   +  712  
             //then later we process those that affect all versions. This could be done with sorting...
    -  717  10
             for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) {
    -  718  176
                 if (!entry.getValue()) {
    -  719  169
                     final DependencyVersion v = parseDependencyVersion(entry.getKey());
    +  713  104
             for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) {
    +  714  1856
                 if (!entry.getValue()) {
    +  715  1800
                     final DependencyVersion v = parseDependencyVersion(entry.getKey());
    +  716   +
                     //this can't dereference a null 'majorVersionMatch' as canSkipVersions accounts for this.
    +  717  1800
                     if (canSkipVersions && !majorVersionMatch.equals(v.getVersionParts().get(0))) {
    +  718  80
                         continue;
    +  719   +
                     }
     720   -
                     //this can't dereference a null 'majorVersionMatch' as canSkipVersions accounts for this.
    -  721  169
                     if (canSkipVersions && !majorVersionMatch.equals(v.getVersionParts().get(0))) {
    -  722  10
                         continue;
    -  723   -
                     }
    +
                     //this can't dereference a null 'identifiedVersion' because if it was null we would have exited
    +  721   +
                     //in the above loop or just after loop (if matchesAnyPrevious return null).
    +  722  1720
                     if (identifiedVersion.equals(v)) {
    +  723  64
                         return entry;
     724   -
                     //this can't dereference a null 'identifiedVersion' because if it was null we would have exited
    +
                     }
     725   -
                     //in the above loop or just after loop (if matchesAnyPrevious return null).
    -  726  159
                     if (identifiedVersion.equals(v)) {
    -  727  8
                         return entry;
    -  728   -
                     }
    -  729  
                 }
    -  730  158
             }
    -  731  2
             for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) {
    -  732  0
                 if (entry.getValue()) {
    -  733  0
                     final DependencyVersion v = parseDependencyVersion(entry.getKey());
    -  734   +  726  1712
             }
    +  727  40
             for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) {
    +  728  448
                 if (entry.getValue()) {
    +  729  0
                     final DependencyVersion v = parseDependencyVersion(entry.getKey());
    +  730  
                     //this can't dereference a null 'majorVersionMatch' as canSkipVersions accounts for this.
    -  735  0
                     if (canSkipVersions && !majorVersionMatch.equals(v.getVersionParts().get(0))) {
    -  736  0
                         continue;
    -  737   +  731  0
                     if (canSkipVersions && !majorVersionMatch.equals(v.getVersionParts().get(0))) {
    +  732  0
                         continue;
    +  733  
                     }
    -  738   +  734  
                     //this can't dereference a null 'identifiedVersion' because if it was null we would have exited
    -  739   +  735  
                     //in the above loop or just after loop (if matchesAnyPrevious return null).
    -  740  0
                     if (entry.getValue() && identifiedVersion.compareTo(v) <= 0) {
    -  741  0
                         if (!(isVersionTwoADifferentProduct && !identifiedVersion.getVersionParts().get(0).equals(v.getVersionParts().get(0)))) {
    -  742  0
                             return entry;
    -  743   +  736  0
                     if (entry.getValue() && identifiedVersion.compareTo(v) <= 0) {
    +  737  0
                         if (!(isVersionTwoADifferentProduct && !identifiedVersion.getVersionParts().get(0).equals(v.getVersionParts().get(0)))) {
    +  738  0
                             return entry;
    +  739  
                         }
    -  744   +  740  
                     }
    +  741   +
                 }
    +  742  448
             }
    +  743  40
             return null;
    +  744   +
         }
     745   -
                 }
    -  746  0
             }
    -  747  2
             return null;
    -  748   -
         }
    -  749  
     
    -  750   +  746  
         /**
    -  751   +  747  
          * Parses the version (including revision) from a CPE identifier. If no version is identified then a '-' is returned.
    -  752   +  748  
          *
    -  753   +  749  
          * @param cpeStr a cpe identifier
    -  754   +  750  
          * @return a dependency version
    -  755   +  751  
          */
    -  756   +  752  
         private DependencyVersion parseDependencyVersion(String cpeStr) {
    -  757  392
             final VulnerableSoftware cpe = new VulnerableSoftware();
    -  758   +  753  4032
             final VulnerableSoftware cpe = new VulnerableSoftware();
    +  754  
             try {
    -  759  392
                 cpe.parseName(cpeStr);
    -  760  0
             } catch (UnsupportedEncodingException ex) {
    -  761   +  755  4032
                 cpe.parseName(cpeStr);
    +  756  0
             } catch (UnsupportedEncodingException ex) {
    +  757  
                 //never going to happen.
    -  762  0
                 LOGGER.log(Level.FINEST, null, ex);
    -  763  392
             }
    -  764  392
             return parseDependencyVersion(cpe);
    -  765   +  758  0
                 LOGGER.trace("", ex);
    +  759  4032
             }
    +  760  4032
             return parseDependencyVersion(cpe);
    +  761  
         }
    -  766   +  762  
     
    -  767   +  763  
         /**
    -  768   +  764  
          * Takes a CPE and parses out the version number. If no version is identified then a '-' is returned.
    -  769   +  765  
          *
    -  770   +  766  
          * @param cpe a cpe object
    -  771   +  767  
          * @return a dependency version
    -  772   +  768  
          */
    -  773   +  769  
         private DependencyVersion parseDependencyVersion(VulnerableSoftware cpe) {
    -  774   +  770  
             DependencyVersion cpeVersion;
    -  775  394
             if (cpe.getVersion() != null && !cpe.getVersion().isEmpty()) {
    -  776   +  771  4056
             if (cpe.getVersion() != null && !cpe.getVersion().isEmpty()) {
    +  772  
                 String versionText;
    -  777  394
                 if (cpe.getRevision() != null && !cpe.getRevision().isEmpty()) {
    -  778  130
                     versionText = String.format("%s.%s", cpe.getVersion(), cpe.getRevision());
    -  779   +  773  4056
                 if (cpe.getUpdate() != null && !cpe.getUpdate().isEmpty()) {
    +  774  1040
                     versionText = String.format("%s.%s", cpe.getVersion(), cpe.getUpdate());
    +  775  
                 } else {
    -  780  264
                     versionText = cpe.getVersion();
    -  781   +  776  3016
                     versionText = cpe.getVersion();
    +  777  
                 }
    -  782  394
                 cpeVersion = DependencyVersionUtil.parseVersion(versionText);
    -  783  394
             } else {
    -  784  0
                 cpeVersion = new DependencyVersion("-");
    -  785   +  778  4056
                 cpeVersion = DependencyVersionUtil.parseVersion(versionText);
    +  779  4056
             } else {
    +  780  0
                 cpeVersion = new DependencyVersion("-");
    +  781  
             }
    -  786  394
             return cpeVersion;
    -  787   +  782  4056
             return cpeVersion;
    +  783  
         }
    +  784   +
     
    +  785   +
         /**
    +  786   +
          * Deletes unused dictionary entries from the database.
    +  787   +
          */
     788   +
         public void deleteUnusedCpe() {
    +  789  0
             CallableStatement cs = null;
    +  790   +
             try {
    +  791  0
                 cs = getConnection().prepareCall(statementBundle.getString("DELETE_UNUSED_DICT_CPE"));
    +  792  0
                 cs.executeUpdate();
    +  793  0
             } catch (SQLException ex) {
    +  794  0
                 LOGGER.error("Unable to delete CPE dictionary entries", ex);
    +  795   +
             } finally {
    +  796  0
                 DBUtils.closeStatement(cs);
    +  797  0
             }
    +  798  0
         }
    +  799   +
     
    +  800   +
         /**
    +  801   +
          * Merges CPE entries into the database.
    +  802   +
          *
    +  803   +
          * @param cpe the CPE identifier
    +  804   +
          * @param vendor the CPE vendor
    +  805   +
          * @param product the CPE product
    +  806   +
          */
    +  807   +
         public void addCpe(String cpe, String vendor, String product) {
    +  808  0
             PreparedStatement ps = null;
    +  809   +
             try {
    +  810  0
                 ps = getConnection().prepareCall(statementBundle.getString("ADD_DICT_CPE"));
    +  811  0
                 ps.setString(1, cpe);
    +  812  0
                 ps.setString(2, vendor);
    +  813  0
                 ps.setString(3, product);
    +  814  0
                 ps.executeUpdate();
    +  815  0
             } catch (SQLException ex) {
    +  816  0
                 LOGGER.error("Unable to add CPE dictionary entry", ex);
    +  817   +
             } finally {
    +  818  0
                 DBUtils.closeStatement(ps);
    +  819  0
             }
    +  820  0
         }
    +  821  
     }
    - + 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 6d700612c..2efff5573 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 7d73e0b3d..5f56c10d2 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 @@ -12,7 +12,7 @@
     
    - +
    Classes in this File Line Coverage Branch Coverage Complexity
    DatabaseProperties
    20%
    7/35
    0%
    0/12
    1.778
    DatabaseProperties
    22%
    8/35
    0%
    0/12
    1.778
     
    @@ -70,13 +70,13 @@  26  
     import java.util.TreeMap;
     27   -
     import java.util.logging.Level;
    +
     import org.owasp.dependencycheck.data.update.nvd.NvdCveInfo;
     28   -
     import java.util.logging.Logger;
    -  29   -
     import org.owasp.dependencycheck.data.update.NvdCveInfo;
    -  30  
     import org.owasp.dependencycheck.data.update.exception.UpdateException;
    +  29   +
     import org.slf4j.Logger;
    +  30   +
     import org.slf4j.LoggerFactory;
     31  
     
     32   @@ -99,13 +99,13 @@
          * The Logger.
     41  
          */
    -  42  1
         private static final Logger LOGGER = Logger.getLogger(DatabaseProperties.class.getName());
    +  42  8
         private static final Logger LOGGER = LoggerFactory.getLogger(DatabaseProperties.class);
     43  
         /**
     44   -
          * Modified key word, used as a key to store information about the modified file (i.e. the containing the last 8
    +
          * Modified key word, used as a key to store information about the modified file (i.e. the containing the last 8 days of
     45   -
          * days of updates)..
    +
          * updates)..
     46  
          */
     47   @@ -113,235 +113,249 @@  48  
         /**
     49   -
          * The properties file key for the last updated field - used to store the last updated time of the Modified NVD CVE
    +
          * The properties file key for the last updated field - used to store the last updated time of the Modified NVD CVE xml file.
     50   -
          * xml file.
    +
          */
     51   -
          */
    -  52  
         public static final String LAST_UPDATED = "NVD CVE Modified";
    +  52   +
         /**
     53   -
         /**
    +
          * Stores the last updated time for each of the NVD CVE files. These timestamps should be updated if we process the modified
     54   -
          * Stores the last updated time for each of the NVD CVE files. These timestamps should be updated if we process the
    +
          * file within 7 days of the last update.
     55   -
          * modified file within 7 days of the last update.
    +
          */
     56   -
          */
    -  57  
         public static final String LAST_UPDATED_BASE = "NVD CVE ";
    +  57   +
         /**
     58   -
         /**
    +
          * The key for the last time the CPE data was updated.
     59   -
          * A collection of properties about the data.
    +
          */
     60   -
          */
    +
         public static final String LAST_CPE_UPDATE = "LAST_CPE_UPDATE";
     61   -
         private Properties properties;
    +
         /**
     62   -
         /**
    +
          * The key for the database schema version.
     63   -
          * A reference to the database.
    +
          */
     64   -
          */
    +
         public static final String VERSION = "version";
     65   -
         private CveDB cveDB;
    +
     
     66   -
     
    +
         /**
     67   -
         /**
    +
          * A collection of properties about the data.
     68   -
          * Constructs a new data properties object.
    -  69   -
          *
    -  70   -
          * @param cveDB the database object holding the properties
    -  71  
          */
    -  72  3
         DatabaseProperties(CveDB cveDB) {
    -  73  3
             this.cveDB = cveDB;
    -  74  3
             loadProperties();
    -  75  3
         }
    -  76   -
     
    -  77   +  69   +
         private Properties properties;
    +  70  
         /**
    +  71   +
          * A reference to the database.
    +  72   +
          */
    +  73   +
         private CveDB cveDB;
    +  74   +
     
    +  75   +
         /**
    +  76   +
          * Constructs a new data properties object.
    +  77   +
          *
     78   -
          * Loads the properties from the database.
    +
          * @param cveDB the database object holding the properties
     79  
          */
    -  80   -
         private void loadProperties() {
    -  81  3
             this.properties = cveDB.getProperties();
    -  82  3
         }
    -  83   -
     
    +  80  48
         DatabaseProperties(CveDB cveDB) {
    +  81  48
             this.cveDB = cveDB;
    +  82  48
             loadProperties();
    +  83  48
         }
     84   -
         /**
    +
     
     85   -
          * Returns whether or not any properties are set.
    +
         /**
     86   -
          *
    +
          * Loads the properties from the database.
     87   -
          * @return whether or not any properties are set
    +
          */
     88   -
          */
    -  89   -
         public boolean isEmpty() {
    -  90  0
             return properties == null || properties.isEmpty();
    +
         private void loadProperties() {
    +  89  48
             this.properties = cveDB.getProperties();
    +  90  48
         }
     91   -
         }
    +
     
     92   -
     
    +
         /**
     93   -
         /**
    +
          * Returns whether or not any properties are set.
     94   -
          * Saves the last updated information to the properties file.
    +
          *
     95   -
          *
    +
          * @return whether or not any properties are set
     96   -
          * @param updatedValue the updated NVD CVE entry
    +
          */
     97   -
          * @throws UpdateException is thrown if there is an update exception
    -  98   -
          */
    +
         public boolean isEmpty() {
    +  98  0
             return properties == null || properties.isEmpty();
     99   -
         public void save(NvdCveInfo updatedValue) throws UpdateException {
    -  100  0
             if (updatedValue == null) {
    -  101  0
                 return;
    +
         }
    +  100   +
     
    +  101   +
         /**
     102   -
             }
    -  103  0
             save(LAST_UPDATED_BASE + updatedValue.getId(), String.valueOf(updatedValue.getTimestamp()));
    -  104  0
         }
    +
          * Saves the last updated information to the properties file.
    +  103   +
          *
    +  104   +
          * @param updatedValue the updated NVD CVE entry
     105   -
     
    -  106   -
         /**
    -  107   -
          * Saves the key value pair to the properties store.
    -  108   -
          *
    -  109   -
          * @param key the property key
    -  110   -
          * @param value the property value
    -  111  
          * @throws UpdateException is thrown if there is an update exception
    -  112   +  106  
          */
    +  107   +
         public void save(NvdCveInfo updatedValue) throws UpdateException {
    +  108  0
             if (updatedValue == null) {
    +  109  0
                 return;
    +  110   +
             }
    +  111  0
             save(LAST_UPDATED_BASE + updatedValue.getId(), String.valueOf(updatedValue.getTimestamp()));
    +  112  0
         }
     113   -
         public void save(String key, String value) throws UpdateException {
    -  114  0
             properties.put(key, value);
    -  115  0
             cveDB.saveProperty(key, value);
    -  116  0
         }
    +
     
    +  114   +
         /**
    +  115   +
          * Saves the key value pair to the properties store.
    +  116   +
          *
     117   -
     
    +
          * @param key the property key
     118   -
         /**
    +
          * @param value the property value
     119   -
          * Returns the property value for the given key. If the key is not contained in the underlying properties null is
    +
          * @throws UpdateException is thrown if there is an update exception
     120   -
          * returned.
    +
          */
     121   -
          *
    -  122   -
          * @param key the property key
    -  123   -
          * @return the value of the property
    -  124   -
          */
    +
         public void save(String key, String value) throws UpdateException {
    +  122  0
             properties.put(key, value);
    +  123  0
             cveDB.saveProperty(key, value);
    +  124  0
         }
     125   -
         public String getProperty(String key) {
    -  126  0
             return properties.getProperty(key);
    +
     
    +  126   +
         /**
     127   -
         }
    +
          * Returns the property value for the given key. If the key is not contained in the underlying properties null is returned.
     128   -
     
    +
          *
     129   -
         /**
    -  130   -
          * Returns the property value for the given key. If the key is not contained in the underlying properties the
    -  131   -
          * default value is returned.
    -  132   -
          *
    -  133  
          * @param key the property key
    -  134   -
          * @param defaultValue the default value
    -  135   +  130  
          * @return the value of the property
    +  131   +
          */
    +  132   +
         public String getProperty(String key) {
    +  133  0
             return properties.getProperty(key);
    +  134   +
         }
    +  135   +
     
     136   -
          */
    +
         /**
     137   -
         public String getProperty(String key, String defaultValue) {
    -  138  0
             return properties.getProperty(key, defaultValue);
    +
          * Returns the property value for the given key. If the key is not contained in the underlying properties the default value is
    +  138   +
          * returned.
     139   -
         }
    +
          *
     140   -
     
    +
          * @param key the property key
     141   -
         /**
    +
          * @param defaultValue the default value
     142   -
          * Returns the collection of Database Properties as a properties collection.
    +
          * @return the value of the property
     143   -
          *
    +
          */
     144   -
          * @return the collection of Database Properties
    -  145   -
          */
    +
         public String getProperty(String key, String defaultValue) {
    +  145  0
             return properties.getProperty(key, defaultValue);
     146   -
         public Properties getProperties() {
    -  147  0
             return properties;
    -  148  
         }
    -  149   +  147  
     
    -  150   +  148  
         /**
    -  151   -
          * Returns a map of the meta data from the database properties. This primarily contains timestamps of when the NVD
    -  152   -
          * CVE information was last updated.
    -  153   +  149   +
          * Returns the collection of Database Properties as a properties collection.
    +  150  
          *
    -  154   -
          * @return a map of the database meta data
    -  155   +  151   +
          * @return the collection of Database Properties
    +  152  
          */
    -  156   -
         public Map<String, String> getMetaData() {
    -  157  0
             final Map<String, String> map = new TreeMap<String, String>();
    -  158  0
             for (Entry<Object, Object> entry : properties.entrySet()) {
    -  159  0
                 final String key = (String) entry.getKey();
    -  160  0
                 if (!"version".equals(key)) {
    -  161  0
                     if (key.startsWith("NVD CVE ")) {
    -  162   -
                         try {
    -  163  0
                             final long epoch = Long.parseLong((String) entry.getValue());
    -  164  0
                             final Date date = new Date(epoch);
    -  165  0
                             final DateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
    -  166  0
                             final String formatted = format.format(date);
    -  167  0
                             map.put(key, formatted);
    -  168  0
                         } catch (Throwable ex) { //deliberately being broad in this catch clause
    -  169  0
                             LOGGER.log(Level.FINE, "Unable to parse timestamp from DB", ex);
    -  170  0
                             map.put(key, (String) entry.getValue());
    -  171  0
                         }
    -  172   -
                     } else {
    -  173  0
                         map.put(key, (String) entry.getValue());
    -  174   -
                     }
    -  175   -
                 }
    -  176  0
             }
    -  177  0
             return map;
    -  178   +  153   +
         public Properties getProperties() {
    +  154  8
             return properties;
    +  155  
         }
    +  156   +
     
    +  157   +
         /**
    +  158   +
          * Returns a map of the meta data from the database properties. This primarily contains timestamps of when the NVD CVE
    +  159   +
          * information was last updated.
    +  160   +
          *
    +  161   +
          * @return a map of the database meta data
    +  162   +
          */
    +  163   +
         public Map<String, String> getMetaData() {
    +  164  0
             final Map<String, String> map = new TreeMap<String, String>();
    +  165  0
             for (Entry<Object, Object> entry : properties.entrySet()) {
    +  166  0
                 final String key = (String) entry.getKey();
    +  167  0
                 if (!"version".equals(key)) {
    +  168  0
                     if (key.startsWith("NVD CVE ")) {
    +  169   +
                         try {
    +  170  0
                             final long epoch = Long.parseLong((String) entry.getValue());
    +  171  0
                             final Date date = new Date(epoch);
    +  172  0
                             final DateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
    +  173  0
                             final String formatted = format.format(date);
    +  174  0
                             map.put(key, formatted);
    +  175  0
                         } catch (Throwable ex) { //deliberately being broad in this catch clause
    +  176  0
                             LOGGER.debug("Unable to parse timestamp from DB", ex);
    +  177  0
                             map.put(key, (String) entry.getValue());
    +  178  0
                         }
     179   +
                     } else {
    +  180  0
                         map.put(key, (String) entry.getValue());
    +  181   +
                     }
    +  182   +
                 }
    +  183  0
             }
    +  184  0
             return map;
    +  185   +
         }
    +  186  
     }
    - + 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 aecea827b..d671aefac 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  24
             super(msg, ex);
    +  58  24
         }
     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 a1ccda824..becb13e04 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 @@ -12,7 +12,7 @@
     
    - +
    Classes in this File Line Coverage Branch Coverage Complexity
    DriverLoader
    55%
    27/49
    100%
    8/8
    4.4
    DriverLoader
    57%
    27/47
    100%
    8/8
    4.4
    DriverLoader$1
    100%
    2/2
    N/A
    4.4
    @@ -57,223 +57,223 @@  19  
     
     20   -
     import java.io.File;
    +
     import org.slf4j.Logger;
     21   -
     import java.net.MalformedURLException;
    +
     import org.slf4j.LoggerFactory;
     22   -
     import java.net.URL;
    +
     
     23   -
     import java.net.URLClassLoader;
    +
     import java.io.File;
     24   -
     import java.security.AccessController;
    +
     import java.net.MalformedURLException;
     25   -
     import java.security.PrivilegedAction;
    +
     import java.net.URL;
     26   -
     import java.sql.Driver;
    +
     import java.net.URLClassLoader;
     27   -
     import java.sql.DriverManager;
    +
     import java.security.AccessController;
     28   -
     import java.sql.SQLException;
    +
     import java.security.PrivilegedAction;
     29   -
     import java.util.ArrayList;
    +
     import java.sql.Driver;
     30   -
     import java.util.List;
    +
     import java.sql.DriverManager;
     31   -
     import java.util.logging.Level;
    +
     import java.sql.SQLException;
     32   -
     import java.util.logging.Logger;
    +
     import java.util.ArrayList;
     33   -
     
    +
     import java.util.List;
     34   -
     /**
    +
     
     35   -
      * DriverLoader is a utility class that is used to load database drivers.
    +
     /**
     36   -
      *
    +
      * DriverLoader is a utility class that is used to load database drivers.
     37   -
      * @author Jeremy Long
    +
      *
     38   -
      */
    +
      * @author Jeremy Long
     39   -
     public final class DriverLoader {
    +
      */
     40   -
     
    +
     public final class DriverLoader {
     41   -
         /**
    +
     
     42   -
          * The logger.
    +
         /**
     43   +
          * The logger.
    +  44  
          */
    -  44  1
         private static final Logger LOGGER = Logger.getLogger(DriverLoader.class.getName());
    -  45   -
     
    +  45  8
         private static final Logger LOGGER = LoggerFactory.getLogger(DriverLoader.class);
     46   -
         /**
    +
     
     47   -
          * Private constructor for a utility class.
    +
         /**
     48   +
          * Private constructor for a utility class.
    +  49  
          */
    -  49  0
         private DriverLoader() {
    -  50  0
         }
    -  51   -
     
    +  50  0
         private DriverLoader() {
    +  51  0
         }
     52   -
         /**
    +
     
     53   -
          * Loads the specified class using the system class loader and registers the driver with the driver manager.
    -  54   -
          *
    -  55   -
          * @param className the fully qualified name of the desired class
    -  56   -
          * @return the loaded Driver
    -  57   -
          * @throws DriverLoadException thrown if the driver cannot be loaded
    -  58   -
          */
    -  59   -
         public static Driver load(String className) throws DriverLoadException {
    -  60  3
             final ClassLoader loader = DriverLoader.class.getClassLoader(); //ClassLoader.getSystemClassLoader();
    -  61  3
             return load(className, loader);
    -  62   -
         }
    -  63   -
     
    -  64  
         /**
    -  65   -
          * Loads the specified class by registering the supplied paths to the class loader and then registers the driver
    -  66   -
          * with the driver manager. The pathToDriver argument is added to the class loader so that an external driver can be
    -  67   -
          * loaded. Note, the pathToDriver can contain a semi-colon separated list of paths so any dependencies can be added
    -  68   -
          * as needed. If a path in the pathToDriver argument is a directory all files in the directory are added to the
    -  69   -
          * class path.
    -  70   +  54   +
          * Loads the specified class using the system class loader and registers the driver with the driver manager.
    +  55  
          *
    -  71   +  56  
          * @param className the fully qualified name of the desired class
    -  72   -
          * @param pathToDriver the path to the JAR file containing the driver; note, this can be a semi-colon separated list
    -  73   -
          * of paths
    -  74   +  57  
          * @return the loaded Driver
    -  75   +  58  
          * @throws DriverLoadException thrown if the driver cannot be loaded
    -  76   +  59  
          */
    -  77   -
         public static Driver load(String className, String pathToDriver) throws DriverLoadException {
    -  78  4
             final URLClassLoader parent = (URLClassLoader) ClassLoader.getSystemClassLoader();
    -  79  4
             final List<URL> urls = new ArrayList<URL>();
    -  80  4
             final String[] paths = pathToDriver.split(File.pathSeparator);
    -  81  9
             for (String path : paths) {
    -  82  5
                 final File file = new File(path);
    -  83  5
                 if (file.isDirectory()) {
    -  84  2
                     final File[] files = file.listFiles();
    -  85   +  60   +
         public static Driver load(String className) throws DriverLoadException {
    +  61  24
             final ClassLoader loader = DriverLoader.class.getClassLoader(); //ClassLoader.getSystemClassLoader();
    +  62  24
             return load(className, loader);
    +  63   +
         }
    +  64  
     
    -  86  35
                     for (File f : files) {
    -  87   +  65   +
         /**
    +  66   +
          * Loads the specified class by registering the supplied paths to the class loader and then registers the driver
    +  67   +
          * with the driver manager. The pathToDriver argument is added to the class loader so that an external driver can be
    +  68   +
          * loaded. Note, the pathToDriver can contain a semi-colon separated list of paths so any dependencies can be added
    +  69   +
          * as needed. If a path in the pathToDriver argument is a directory all files in the directory are added to the
    +  70   +
          * class path.
    +  71   +
          *
    +  72   +
          * @param className the fully qualified name of the desired class
    +  73   +
          * @param pathToDriver the path to the JAR file containing the driver; note, this can be a semi-colon separated list
    +  74   +
          * of paths
    +  75   +
          * @return the loaded Driver
    +  76   +
          * @throws DriverLoadException thrown if the driver cannot be loaded
    +  77   +
          */
    +  78   +
         public static Driver load(String className, String pathToDriver) throws DriverLoadException {
    +  79  32
             final URLClassLoader parent = (URLClassLoader) ClassLoader.getSystemClassLoader();
    +  80  32
             final List<URL> urls = new ArrayList<URL>();
    +  81  32
             final String[] paths = pathToDriver.split(File.pathSeparator);
    +  82  72
             for (String path : paths) {
    +  83  40
                 final File file = new File(path);
    +  84  40
                 if (file.isDirectory()) {
    +  85  16
                     final File[] files = file.listFiles();
    +  86   +
     
    +  87  264
                     for (File f : files) {
    +  88  
                         try {
    -  88  33
                             urls.add(f.toURI().toURL());
    -  89  0
                         } catch (MalformedURLException ex) {
    -  90  0
                             final String msg = String.format("Unable to load database driver '%s'; invalid path provided '%s'",
    -  91   -
                                     className, f.getAbsoluteFile());
    -  92  0
                             LOGGER.log(Level.FINE, msg, ex);
    -  93  0
                             throw new DriverLoadException(msg, ex);
    -  94  33
                         }
    +  89  248
                             urls.add(f.toURI().toURL());
    +  90  0
                         } catch (MalformedURLException ex) {
    +  91  0
                             LOGGER.debug("Unable to load database driver '{}'; invalid path provided '{}'",
    +  92   +
                                 className, f.getAbsoluteFile(), ex);
    +  93  0
                             throw new DriverLoadException("Unable to load database driver. Invalid path provided", ex);
    +  94  248
                         }
     95  
                     }
    -  96  2
                 } else if (file.exists()) {
    +  96  16
                 } else if (file.exists()) {
     97  
                     try {
    -  98  2
                         urls.add(file.toURI().toURL());
    +  98  16
                         urls.add(file.toURI().toURL());
     99  0
                     } catch (MalformedURLException ex) {
    -  100  0
                         final String msg = String.format("Unable to load database driver '%s'; invalid path provided '%s'",
    +  100  0
                         LOGGER.debug("Unable to load database driver '{}'; invalid path provided '{}'",
     101   -
                                 className, file.getAbsoluteFile());
    -  102  0
                         LOGGER.log(Level.FINE, msg, ex);
    -  103  0
                         throw new DriverLoadException(msg, ex);
    -  104  2
                     }
    +
                             className, file.getAbsoluteFile(), ex);
    +  102  0
                         throw new DriverLoadException("Unable to load database driver. Invalid path provided", ex);
    +  103  16
                     }
    +  104   +
                 }
     105   -
                 }
    -  106  
             }
    -  107  8
             final URLClassLoader loader = AccessController.doPrivileged(new PrivilegedAction<URLClassLoader>() {
    -  108   +  106  64
             final URLClassLoader loader = AccessController.doPrivileged(new PrivilegedAction<URLClassLoader>() {
    +  107  
                 @Override
    -  109   +  108  
                 public URLClassLoader run() {
    -  110  4
                     return new URLClassLoader(urls.toArray(new URL[urls.size()]), parent);
    -  111   +  109  32
                     return new URLClassLoader(urls.toArray(new URL[urls.size()]), parent);
    +  110  
                 }
    -  112   +  111  
             });
    -  113   +  112  
     
    -  114  4
             return load(className, loader);
    +  113  32
             return load(className, loader);
    +  114   +
         }
     115   -
         }
    -  116  
     
    -  117   +  116  
         /**
    -  118   +  117  
          * Loads the specified class using the supplied class loader and registers the driver with the driver manager.
    -  119   +  118  
          *
    -  120   +  119  
          * @param className the fully qualified name of the desired class
    -  121   +  120  
          * @param loader the class loader to use when loading the driver
    -  122   +  121  
          * @return the loaded Driver
    -  123   +  122  
          * @throws DriverLoadException thrown if the driver cannot be loaded
    -  124   +  123  
          */
    -  125   +  124  
         private static Driver load(String className, ClassLoader loader) throws DriverLoadException {
    -  126   +  125  
             try {
    -  127  7
                 final Class c = Class.forName(className, true, loader);
    -  128   +  126  56
                 final Class c = Class.forName(className, true, loader);
    +  127  
                 //final Class c = loader.loadClass(className);
    -  129  4
                 final Driver driver = (Driver) c.newInstance();
    -  130  4
                 final Driver shim = new DriverShim(driver);
    -  131   +  128  32
                 final Driver driver = (Driver) c.newInstance();
    +  129  32
                 final Driver shim = new DriverShim(driver);
    +  130  
                 //using the DriverShim to get around the fact that the DriverManager won't register a driver not in the base class path
    -  132  4
                 DriverManager.registerDriver(shim);
    -  133  4
                 return shim;
    -  134  3
             } catch (ClassNotFoundException ex) {
    -  135  3
                 final String msg = String.format("Unable to load database driver '%s'", className);
    -  136  3
                 LOGGER.log(Level.FINE, msg, ex);
    -  137  3
                 throw new DriverLoadException(msg, ex);
    -  138  0
             } catch (InstantiationException ex) {
    -  139  0
                 final String msg = String.format("Unable to load database driver '%s'", className);
    -  140  0
                 LOGGER.log(Level.FINE, msg, ex);
    -  141  0
                 throw new DriverLoadException(msg, ex);
    -  142  0
             } catch (IllegalAccessException ex) {
    -  143  0
                 final String msg = String.format("Unable to load database driver '%s'", className);
    -  144  0
                 LOGGER.log(Level.FINE, msg, ex);
    -  145  0
                 throw new DriverLoadException(msg, ex);
    -  146  0
             } catch (SQLException ex) {
    -  147  0
                 final String msg = String.format("Unable to load database driver '%s'", className);
    -  148  0
                 LOGGER.log(Level.FINE, msg, ex);
    -  149  0
                 throw new DriverLoadException(msg, ex);
    -  150   +  131  32
                 DriverManager.registerDriver(shim);
    +  132  32
                 return shim;
    +  133  24
             } catch (ClassNotFoundException ex) {
    +  134  24
                 final String msg = String.format("Unable to load database driver '%s'", className);
    +  135  24
                 LOGGER.debug(msg, ex);
    +  136  24
                 throw new DriverLoadException(msg, ex);
    +  137  0
             } catch (InstantiationException ex) {
    +  138  0
                 final String msg = String.format("Unable to load database driver '%s'", className);
    +  139  0
                 LOGGER.debug(msg, ex);
    +  140  0
                 throw new DriverLoadException(msg, ex);
    +  141  0
             } catch (IllegalAccessException ex) {
    +  142  0
                 final String msg = String.format("Unable to load database driver '%s'", className);
    +  143  0
                 LOGGER.debug(msg, ex);
    +  144  0
                 throw new DriverLoadException(msg, ex);
    +  145  0
             } catch (SQLException ex) {
    +  146  0
                 final String msg = String.format("Unable to load database driver '%s'", className);
    +  147  0
                 LOGGER.debug(msg, ex);
    +  148  0
                 throw new DriverLoadException(msg, ex);
    +  149  
             }
    -  151   +  150  
         }
    -  152   +  151  
     }
    - + 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 1387a0384..6ff64bb63 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 @@ -56,342 +56,344 @@  19  
     
     20   -
     import java.lang.reflect.InvocationTargetException;
    +
     import org.slf4j.Logger;
     21   -
     import java.lang.reflect.Method;
    +
     import org.slf4j.LoggerFactory;
     22   -
     import java.sql.Connection;
    +
     
     23   -
     import java.sql.Driver;
    +
     import java.lang.reflect.InvocationTargetException;
     24   -
     import java.sql.DriverPropertyInfo;
    +
     import java.lang.reflect.Method;
     25   -
     import java.sql.SQLException;
    +
     import java.sql.Connection;
     26   -
     import java.sql.SQLFeatureNotSupportedException;
    +
     import java.sql.Driver;
     27   -
     import java.util.Properties;
    +
     import java.sql.DriverPropertyInfo;
     28   -
     import java.util.logging.Level;
    +
     import java.sql.SQLException;
     29   -
     import java.util.logging.Logger;
    +
     import java.sql.SQLFeatureNotSupportedException;
     30   -
     
    +
     import java.util.Properties;
     31   -
     /**
    +
     
     32   -
      * <p>
    +
     /**
     33   -
      * Driver shim to get around the class loader issue with the DriverManager. The following code is a nearly identical
    +
      * <p>
     34   -
      * copy (with more comments and a few more methods implemented) of the DriverShim from:</p>
    +
      * Driver shim to get around the class loader issue with the DriverManager. The following code is a nearly identical
     35   -
      * <blockquote>http://www.kfu.com/~nsayer/Java/dyn-jdbc.html</blockquote>
    +
      * copy (with more comments and a few more methods implemented) of the DriverShim from:</p>
     36   -
      *
    +
      * <blockquote>http://www.kfu.com/~nsayer/Java/dyn-jdbc.html</blockquote>
     37   -
      * @author Jeremy Long
    +
      *
     38   -
      * @see java.sql.Driver
    +
      * @author Jeremy Long
     39   -
      */
    +
      * @see java.sql.Driver
     40   -
     class DriverShim implements Driver {
    +
      */
     41   -
     
    +
     class DriverShim implements Driver {
     42   -
         /**
    +
     
     43   -
          * The logger.
    +
         /**
     44   +
          * The logger.
    +  45  
          */
    -  45  1
         private static final Logger LOGGER = Logger.getLogger(DriverShim.class.getName());
    -  46   -
         /**
    +  46  8
         private static final Logger LOGGER = LoggerFactory.getLogger(DriverShim.class);
     47   -
          * The database driver being wrapped.
    +
         /**
     48   -
          */
    +
          * The database driver being wrapped.
     49   -
         private final Driver driver;
    +
          */
     50   -
     
    +
         private final Driver driver;
     51   -
         /**
    +
     
     52   -
          * Constructs a new wrapper around a Driver.
    +
         /**
     53   -
          *
    +
          * Constructs a new wrapper around a Driver.
     54   -
          * @param driver the database driver to wrap
    +
          *
     55   +
          * @param driver the database driver to wrap
    +  56  
          */
    -  56  4
         DriverShim(Driver driver) {
    -  57  4
             this.driver = driver;
    -  58  4
         }
    -  59   -
     
    +  57  32
         DriverShim(Driver driver) {
    +  58  32
             this.driver = driver;
    +  59  32
         }
     60   -
         /**
    +
     
     61   -
          * Wraps the underlying driver's call to acceptsURL. Returns whether or not the driver can open a connection to the
    +
         /**
     62   -
          * given URL.
    +
          * Wraps the underlying driver's call to acceptsURL. Returns whether or not the driver can open a connection to the
     63   -
          *
    +
          * given URL.
     64   -
          * @param url the URL of the database
    +
          *
     65   -
          * @return true if the wrapped driver can connect to the specified URL
    +
          * @param url the URL of the database
     66   -
          * @throws SQLException thrown if there is an error connecting to the database
    +
          * @return true if the wrapped driver can connect to the specified URL
     67   -
          * @see java.sql.Driver#acceptsURL(java.lang.String)
    -  68   -
          */
    -  69   -
         @Override
    -  70   -
         public boolean acceptsURL(String url) throws SQLException {
    -  71  2
             return this.driver.acceptsURL(url);
    -  72   -
         }
    -  73   -
     
    -  74   -
         /**
    -  75   -
          * Wraps the call to the underlying driver's connect method.
    -  76   -
          *
    -  77   -
          * @param url the URL of the database
    -  78   -
          * @param info a collection of string/value pairs
    -  79   -
          * @return a Connection object
    -  80  
          * @throws SQLException thrown if there is an error connecting to the database
    -  81   -
          * @see java.sql.Driver#connect(java.lang.String, java.util.Properties)
    -  82   +  68   +
          * @see java.sql.Driver#acceptsURL(java.lang.String)
    +  69  
          */
    -  83   +  70  
         @Override
    -  84   -
         public Connection connect(String url, Properties info) throws SQLException {
    -  85  0
             return this.driver.connect(url, info);
    -  86   +  71   +
         public boolean acceptsURL(String url) throws SQLException {
    +  72  16
             return this.driver.acceptsURL(url);
    +  73  
         }
    -  87   +  74  
     
    -  88   +  75  
         /**
    -  89   -
          * Returns the wrapped driver's major version number.
    -  90   +  76   +
          * Wraps the call to the underlying driver's connect method.
    +  77  
          *
    -  91   -
          * @return the wrapped driver's major version number
    -  92   -
          * @see java.sql.Driver#getMajorVersion()
    -  93   -
          */
    -  94   -
         @Override
    -  95   -
         public int getMajorVersion() {
    -  96  0
             return this.driver.getMajorVersion();
    -  97   -
         }
    -  98   -
     
    -  99   -
         /**
    -  100   -
          * Returns the wrapped driver's minor version number.
    -  101   -
          *
    -  102   -
          * @return the wrapped driver's minor version number
    -  103   -
          * @see java.sql.Driver#getMinorVersion()
    -  104   -
          */
    -  105   -
         @Override
    -  106   -
         public int getMinorVersion() {
    -  107  0
             return this.driver.getMinorVersion();
    -  108   -
         }
    -  109   -
     
    -  110   -
         /**
    -  111   -
          * Wraps the call to the underlying driver's getParentLogger method.
    -  112   -
          *
    -  113   -
          * @return the parent's Logger
    -  114   -
          * @throws SQLFeatureNotSupportedException thrown if the feature is not supported
    -  115   -
          * @see java.sql.Driver#getParentLogger()
    -  116   -
          */
    -  117   -
         //@Override
    -  118   -
         public Logger getParentLogger() throws SQLFeatureNotSupportedException {
    -  119   -
             //return driver.getParentLogger();
    -  120  0
             Method m = null;
    -  121   -
             try {
    -  122  0
                 m = driver.getClass().getMethod("getParentLogger");
    -  123  0
             } catch (Throwable e) {
    -  124  0
                 throw new SQLFeatureNotSupportedException();
    -  125  0
             }
    -  126  0
             if (m != null) {
    -  127   -
                 try {
    -  128  0
                     return (Logger) m.invoke(m);
    -  129  0
                 } catch (IllegalAccessException ex) {
    -  130  0
                     LOGGER.log(Level.FINER, null, ex);
    -  131  0
                 } catch (IllegalArgumentException ex) {
    -  132  0
                     LOGGER.log(Level.FINER, null, ex);
    -  133  0
                 } catch (InvocationTargetException ex) {
    -  134  0
                     LOGGER.log(Level.FINER, null, ex);
    -  135  0
                 }
    -  136   -
             }
    -  137  0
             throw new SQLFeatureNotSupportedException();
    -  138   -
         }
    -  139   -
     
    -  140   -
         /**
    -  141   -
          * Wraps the call to the underlying driver's getPropertyInfo method.
    -  142   -
          *
    -  143   +  78  
          * @param url the URL of the database
    -  144   +  79  
          * @param info a collection of string/value pairs
    +  80   +
          * @return a Connection object
    +  81   +
          * @throws SQLException thrown if there is an error connecting to the database
    +  82   +
          * @see java.sql.Driver#connect(java.lang.String, java.util.Properties)
    +  83   +
          */
    +  84   +
         @Override
    +  85   +
         public Connection connect(String url, Properties info) throws SQLException {
    +  86  0
             return this.driver.connect(url, info);
    +  87   +
         }
    +  88   +
     
    +  89   +
         /**
    +  90   +
          * Returns the wrapped driver's major version number.
    +  91   +
          *
    +  92   +
          * @return the wrapped driver's major version number
    +  93   +
          * @see java.sql.Driver#getMajorVersion()
    +  94   +
          */
    +  95   +
         @Override
    +  96   +
         public int getMajorVersion() {
    +  97  0
             return this.driver.getMajorVersion();
    +  98   +
         }
    +  99   +
     
    +  100   +
         /**
    +  101   +
          * Returns the wrapped driver's minor version number.
    +  102   +
          *
    +  103   +
          * @return the wrapped driver's minor version number
    +  104   +
          * @see java.sql.Driver#getMinorVersion()
    +  105   +
          */
    +  106   +
         @Override
    +  107   +
         public int getMinorVersion() {
    +  108  0
             return this.driver.getMinorVersion();
    +  109   +
         }
    +  110   +
     
    +  111   +
         /**
    +  112   +
          * Wraps the call to the underlying driver's getParentLogger method.
    +  113   +
          *
    +  114   +
          * @return the parent's Logger
    +  115   +
          * @throws SQLFeatureNotSupportedException thrown if the feature is not supported
    +  116   +
          * @see java.sql.Driver#getParentLogger()
    +  117   +
          */
    +  118   +
         //@Override
    +  119   +
         public java.util.logging.Logger getParentLogger() throws SQLFeatureNotSupportedException {
    +  120   +
             //return driver.getParentLogger();
    +  121  0
             Method m = null;
    +  122   +
             try {
    +  123  0
                 m = driver.getClass().getMethod("getParentLogger");
    +  124  0
             } catch (Throwable e) {
    +  125  0
                 throw new SQLFeatureNotSupportedException();
    +  126  0
             }
    +  127  0
             if (m != null) {
    +  128   +
                 try {
    +  129  0
                     return (java.util.logging.Logger) m.invoke(m);
    +  130  0
                 } catch (IllegalAccessException ex) {
    +  131  0
                     LOGGER.trace("", ex);
    +  132  0
                 } catch (IllegalArgumentException ex) {
    +  133  0
                     LOGGER.trace("", ex);
    +  134  0
                 } catch (InvocationTargetException ex) {
    +  135  0
                     LOGGER.trace("", ex);
    +  136  0
                 }
    +  137   +
             }
    +  138  0
             throw new SQLFeatureNotSupportedException();
    +  139   +
         }
    +  140   +
     
    +  141   +
         /**
    +  142   +
          * Wraps the call to the underlying driver's getPropertyInfo method.
    +  143   +
          *
    +  144   +
          * @param url the URL of the database
     145   -
          * @return an array of DriverPropertyInfo objects
    +
          * @param info a collection of string/value pairs
     146   -
          * @throws SQLException thrown if there is an error accessing the database
    +
          * @return an array of DriverPropertyInfo objects
     147   -
          * @see java.sql.Driver#getPropertyInfo(java.lang.String, java.util.Properties)
    +
          * @throws SQLException thrown if there is an error accessing the database
     148   -
          */
    +
          * @see java.sql.Driver#getPropertyInfo(java.lang.String, java.util.Properties)
     149   -
         @Override
    +
          */
     150   +
         @Override
    +  151  
         public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException {
    -  151  0
             return this.driver.getPropertyInfo(url, info);
    -  152   -
         }
    +  152  0
             return this.driver.getPropertyInfo(url, info);
     153   -
     
    +
         }
     154   -
         /**
    +
     
     155   -
          * Returns whether or not the wrapped driver is jdbcCompliant.
    +
         /**
     156   -
          *
    +
          * Returns whether or not the wrapped driver is jdbcCompliant.
     157   -
          * @return true if the wrapped driver is JDBC compliant; otherwise false
    +
          *
     158   -
          * @see java.sql.Driver#jdbcCompliant()
    +
          * @return true if the wrapped driver is JDBC compliant; otherwise false
     159   -
          */
    +
          * @see java.sql.Driver#jdbcCompliant()
     160   -
         @Override
    +
          */
     161   +
         @Override
    +  162  
         public boolean jdbcCompliant() {
    -  162  0
             return this.driver.jdbcCompliant();
    -  163   -
         }
    +  163  0
             return this.driver.jdbcCompliant();
     164   -
     
    +
         }
     165   -
         /**
    +
     
     166   -
          * Standard implementation of hashCode.
    +
         /**
     167   -
          *
    +
          * Standard implementation of hashCode.
     168   -
          * @return the hashCode of the object
    +
          *
     169   -
          */
    +
          * @return the hashCode of the object
     170   -
         @Override
    +
          */
     171   +
         @Override
    +  172  
         public int hashCode() {
    -  172  0
             int hash = 7;
    -  173  0
             hash = 97 * hash + (this.driver != null ? this.driver.hashCode() : 0);
    -  174  0
             return hash;
    -  175   -
         }
    +  173  0
             int hash = 7;
    +  174  0
             hash = 97 * hash + (this.driver != null ? this.driver.hashCode() : 0);
    +  175  0
             return hash;
     176   -
     
    +
         }
     177   -
         /**
    -  178   -
          * Standard implementation of equals.
    -  179   -
          *
    -  180   -
          * @param obj the object to compare
    -  181   -
          * @return returns true if the objects are equal; otherwise false
    -  182   -
          */
    -  183   -
         @Override
    -  184   -
         public boolean equals(Object obj) {
    -  185  0
             if (obj == null) {
    -  186  0
                 return false;
    -  187   -
             }
    -  188  0
             if (getClass() != obj.getClass()) {
    -  189  0
                 return false;
    -  190   -
             }
    -  191  0
             final DriverShim other = (DriverShim) obj;
    -  192  0
             return this.driver == other.driver || (this.driver != null && this.driver.equals(other.driver));
    -  193   -
         }
    -  194  
     
    -  195   +  178  
         /**
    -  196   -
          * Standard implementation of toString().
    -  197   +  179   +
          * Standard implementation of equals.
    +  180  
          *
    -  198   -
          * @return the String representation of the object
    -  199   +  181   +
          * @param obj the object to compare
    +  182   +
          * @return returns true if the objects are equal; otherwise false
    +  183  
          */
    -  200   +  184  
         @Override
    -  201   -
         public String toString() {
    -  202  7
             return "DriverShim{" + "driver=" + driver + '}';
    -  203   +  185   +
         public boolean equals(Object obj) {
    +  186  0
             if (obj == null) {
    +  187  0
                 return false;
    +  188   +
             }
    +  189  0
             if (getClass() != obj.getClass()) {
    +  190  0
                 return false;
    +  191   +
             }
    +  192  0
             final DriverShim other = (DriverShim) obj;
    +  193  0
             return this.driver == other.driver || (this.driver != null && this.driver.equals(other.driver));
    +  194  
         }
    +  195   +
     
    +  196   +
         /**
    +  197   +
          * Standard implementation of toString().
    +  198   +
          *
    +  199   +
          * @return the String representation of the object
    +  200   +
          */
    +  201   +
         @Override
    +  202   +
         public String toString() {
    +  203  56
             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 new file mode 100644 index 000000000..f530bff03 --- /dev/null +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.BaseUpdater.html @@ -0,0 +1,176 @@ + + + + +Coverage Report + + + + +
    Coverage Report - org.owasp.dependencycheck.data.update.BaseUpdater
    +
     
    + + + + +
    Classes in this File Line Coverage Branch Coverage Complexity
    BaseUpdater
    70%
    17/24
    50%
    2/4
    2.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) 2015 Jeremy Long. All Rights Reserved.
     17  
      */
     18  
     package org.owasp.dependencycheck.data.update;
     19  
     
     20  
     import org.owasp.dependencycheck.data.nvdcve.CveDB;
     21  
     import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
     22  
     import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties;
     23  
     import org.owasp.dependencycheck.data.update.exception.UpdateException;
     24  
     import org.slf4j.Logger;
     25  
     import org.slf4j.LoggerFactory;
     26  
     
     27  
     /**
     28  
      *
     29  
      * @author Jeremy Long
     30  
      */
     31  32
     public abstract class BaseUpdater {
     32  
     
     33  
         /**
     34  
          * Static logger.
     35  
          */
     36  8
         private static final Logger LOGGER = LoggerFactory.getLogger(BaseUpdater.class);
     37  
         /**
     38  
          * Information about the timestamps and URLs for data that needs to be updated.
     39  
          */
     40  
         private DatabaseProperties properties;
     41  
         /**
     42  
          * Reference to the Cve Database.
     43  
          */
     44  32
         private CveDB cveDB = null;
     45  
     
     46  
         protected CveDB getCveDB() {
     47  8
             return cveDB;
     48  
         }
     49  
     
     50  
         protected DatabaseProperties getProperties() {
     51  8
             return properties;
     52  
         }
     53  
     
     54  
         /**
     55  
          * Closes the CVE and CPE data stores.
     56  
          */
     57  
         protected void closeDataStores() {
     58  24
             if (cveDB != null) {
     59  
                 try {
     60  24
                     cveDB.close();
     61  24
                     cveDB = null;
     62  24
                     properties = null;
     63  0
                 } catch (Throwable ignore) {
     64  0
                     LOGGER.trace("Error closing the database", ignore);
     65  24
                 }
     66  
             }
     67  24
         }
     68  
     
     69  
         /**
     70  
          * Opens the data store.
     71  
          *
     72  
          * @throws UpdateException thrown if a data store cannot be opened
     73  
          */
     74  
         protected final void openDataStores() throws UpdateException {
     75  24
             if (cveDB != null) {
     76  0
                 return;
     77  
             }
     78  
             try {
     79  24
                 cveDB = new CveDB();
     80  24
                 cveDB.open();
     81  24
                 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  24
             }
     87  24
         }
     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 58f0dc45e..266eaac76 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 new file mode 100644 index 000000000..eeb1a4bf2 --- /dev/null +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.CpeUpdater.html @@ -0,0 +1,345 @@ + + + + +Coverage Report + + + + +
    Coverage Report - org.owasp.dependencycheck.data.update.CpeUpdater
    +
     
    + + + + +
    Classes in this File Line Coverage Branch Coverage Complexity
    CpeUpdater
    0%
    0/75
    0%
    0/26
    6.6
    +
     
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
     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) 2015 Jeremy Long. All Rights Reserved.
     17  
      */
     18  
     package org.owasp.dependencycheck.data.update;
     19  
     
     20  
     import java.io.File;
     21  
     import java.io.FileInputStream;
     22  
     import java.io.FileNotFoundException;
     23  
     import java.io.FileOutputStream;
     24  
     import java.io.IOException;
     25  
     import java.net.MalformedURLException;
     26  
     import java.net.URL;
     27  
     import java.util.Date;
     28  
     import java.util.List;
     29  
     import java.util.zip.GZIPInputStream;
     30  
     import javax.xml.parsers.ParserConfigurationException;
     31  
     import javax.xml.parsers.SAXParser;
     32  
     import javax.xml.parsers.SAXParserFactory;
     33  
     import org.apache.commons.io.FileUtils;
     34  
     import static org.owasp.dependencycheck.data.nvdcve.DatabaseProperties.LAST_CPE_UPDATE;
     35  
     import org.owasp.dependencycheck.data.update.cpe.CPEHandler;
     36  
     import org.owasp.dependencycheck.data.update.cpe.Cpe;
     37  
     import org.owasp.dependencycheck.data.update.exception.UpdateException;
     38  
     import org.owasp.dependencycheck.utils.DateUtil;
     39  
     import org.owasp.dependencycheck.utils.DownloadFailedException;
     40  
     import org.owasp.dependencycheck.utils.Downloader;
     41  
     import org.owasp.dependencycheck.utils.Settings;
     42  
     import org.slf4j.Logger;
     43  
     import org.slf4j.LoggerFactory;
     44  
     import org.xml.sax.SAXException;
     45  
     
     46  
     /**
     47  
      * The CpeUpdater is designed to download the CPE data file from NIST and import the data into the database. However, as this
     48  
      * currently adds no beneficial data, compared to what is in the CPE data contained in the CVE data files, this class is not
     49  
      * currently used. The code is being kept as a future update may utilize more data from the CPE xml files.
     50  
      *
     51  
      * @author Jeremy Long
     52  
      */
     53  0
     public class CpeUpdater extends BaseUpdater implements CachedWebDataSource {
     54  
     
     55  
         /**
     56  
          * Static logger.
     57  
          */
     58  0
         private static final Logger LOGGER = LoggerFactory.getLogger(CpeUpdater.class);
     59  
     
     60  
         @Override
     61  
         public void update() throws UpdateException {
     62  
             try {
     63  0
                 openDataStores();
     64  0
                 if (updateNeeded()) {
     65  0
                     LOGGER.info("Updating the Common Platform Enumeration (CPE)");
     66  0
                     final File xml = downloadCpe();
     67  0
                     final List<Cpe> cpes = processXML(xml);
     68  0
                     getCveDB().deleteUnusedCpe();
     69  0
                     for (Cpe cpe : cpes) {
     70  0
                         getCveDB().addCpe(cpe.getValue(), cpe.getVendor(), cpe.getProduct());
     71  0
                     }
     72  0
                     final Date now = new Date();
     73  0
                     getProperties().save(LAST_CPE_UPDATE, Long.toString(now.getTime()));
     74  0
                     LOGGER.info("CPE update complete");
     75  
                 }
     76  
             } finally {
     77  0
                 closeDataStores();
     78  0
             }
     79  0
         }
     80  
     
     81  
         /**
     82  
          * Downloads the CPE XML file.
     83  
          *
     84  
          * @return the file reference to the CPE.xml file
     85  
          * @throws UpdateException thrown if there is an issue downloading the XML file
     86  
          */
     87  
         private File downloadCpe() throws UpdateException {
     88  
             File xml;
     89  
             final URL url;
     90  
             try {
     91  0
                 url = new URL(Settings.getString(Settings.KEYS.CPE_URL));
     92  0
                 xml = File.createTempFile("cpe", ".xml", Settings.getTempDirectory());
     93  0
                 Downloader.fetchFile(url, xml);
     94  0
                 if (url.toExternalForm().endsWith(".xml.gz")) {
     95  0
                     extractGzip(xml);
     96  
                 }
     97  
     
     98  0
             } catch (MalformedURLException ex) {
     99  0
                 throw new UpdateException("Invalid CPE URL", ex);
     100  0
             } catch (DownloadFailedException ex) {
     101  0
                 throw new UpdateException("Unable to download CPE XML file", ex);
     102  0
             } catch (IOException ex) {
     103  0
                 throw new UpdateException("Unable to create temporary file to download CPE", ex);
     104  0
             }
     105  0
             return xml;
     106  
         }
     107  
     
     108  
         /**
     109  
          * Parses the CPE XML file to return a list of CPE entries.
     110  
          *
     111  
          * @param xml the CPE data file
     112  
          * @return the list of CPE entries
     113  
          * @throws UpdateException thrown if there is an issue with parsing the XML file
     114  
          */
     115  
         private List<Cpe> processXML(final File xml) throws UpdateException {
     116  
             try {
     117  0
                 final SAXParserFactory factory = SAXParserFactory.newInstance();
     118  0
                 final SAXParser saxParser = factory.newSAXParser();
     119  0
                 final CPEHandler handler = new CPEHandler();
     120  0
                 saxParser.parse(xml, handler);
     121  0
                 return handler.getData();
     122  0
             } catch (ParserConfigurationException ex) {
     123  0
                 throw new UpdateException("Unable to parse CPE XML file due to SAX Parser Issue", ex);
     124  0
             } catch (SAXException ex) {
     125  0
                 throw new UpdateException("Unable to parse CPE XML file due to SAX Parser Exception", ex);
     126  0
             } catch (IOException ex) {
     127  0
                 throw new UpdateException("Unable to parse CPE XML file due to IO Failure", ex);
     128  
             }
     129  
         }
     130  
     
     131  
         /**
     132  
          * Checks to find the last time the CPE data was refreshed and if it needs to be updated.
     133  
          *
     134  
          * @return true if the CPE data should be refreshed
     135  
          */
     136  
         private boolean updateNeeded() {
     137  0
             final Date now = new Date();
     138  0
             final int days = Settings.getInt(Settings.KEYS.CVE_MODIFIED_VALID_FOR_DAYS, 30);
     139  0
             long timestamp = 0;
     140  0
             final String ts = getProperties().getProperty(LAST_CPE_UPDATE);
     141  0
             if (ts != null && ts.matches("^[0-9]+$")) {
     142  0
                 timestamp = Long.parseLong(ts);
     143  
             }
     144  0
             return !DateUtil.withinDateRange(timestamp, now.getTime(), days);
     145  
         }
     146  
     
     147  
         /**
     148  
          * Extracts the file contained in a gzip archive. The extracted file is placed in the exact same path as the file specified.
     149  
          *
     150  
          * @param file the archive file
     151  
          * @throws FileNotFoundException thrown if the file does not exist
     152  
          * @throws IOException thrown if there is an error extracting the file.
     153  
          */
     154  
         private void extractGzip(File file) throws FileNotFoundException, IOException {
     155  
             //TODO - move this to a util class as it is duplicative of (copy of) code in the DownloadTask
     156  0
             final String originalPath = file.getPath();
     157  0
             final File gzip = new File(originalPath + ".gz");
     158  0
             if (gzip.isFile() && !gzip.delete()) {
     159  0
                 gzip.deleteOnExit();
     160  
             }
     161  0
             if (!file.renameTo(gzip)) {
     162  0
                 throw new IOException("Unable to rename '" + file.getPath() + "'");
     163  
             }
     164  0
             final File newfile = new File(originalPath);
     165  
     
     166  0
             final byte[] buffer = new byte[4096];
     167  
     
     168  0
             GZIPInputStream cin = null;
     169  0
             FileOutputStream out = null;
     170  
             try {
     171  0
                 cin = new GZIPInputStream(new FileInputStream(gzip));
     172  0
                 out = new FileOutputStream(newfile);
     173  
     
     174  
                 int len;
     175  0
                 while ((len = cin.read(buffer)) > 0) {
     176  0
                     out.write(buffer, 0, len);
     177  
                 }
     178  
             } finally {
     179  0
                 if (cin != null) {
     180  
                     try {
     181  0
                         cin.close();
     182  0
                     } catch (IOException ex) {
     183  0
                         LOGGER.trace("ignore", ex);
     184  0
                     }
     185  
                 }
     186  0
                 if (out != null) {
     187  
                     try {
     188  0
                         out.close();
     189  0
                     } catch (IOException ex) {
     190  0
                         LOGGER.trace("ignore", ex);
     191  0
                     }
     192  
                 }
     193  0
                 if (gzip.isFile()) {
     194  0
                     FileUtils.deleteQuietly(gzip);
     195  
                 }
     196  
             }
     197  0
         }
     198  
     }
    + + + + 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 d44af41d6..224e4af15 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 @@ -12,7 +12,7 @@
     
    - +
    Classes in this File Line Coverage Branch Coverage Complexity
    EngineVersionCheck
    47%
    37/78
    50%
    13/26
    4.286
    EngineVersionCheck
    51%
    40/78
    53%
    14/26
    4.286
     
    @@ -66,29 +66,29 @@  24  
     import java.util.Date;
     25   -
     import java.util.logging.Level;
    -  26   -
     import java.util.logging.Logger;
    -  27  
     import org.apache.commons.io.IOUtils;
    -  28   +  26  
     import org.owasp.dependencycheck.data.nvdcve.CveDB;
    -  29   +  27  
     import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
    -  30   +  28  
     import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties;
    -  31   +  29  
     import org.owasp.dependencycheck.data.update.exception.UpdateException;
    -  32   +  30  
     import org.owasp.dependencycheck.utils.DateUtil;
    -  33   +  31  
     import org.owasp.dependencycheck.utils.DependencyVersion;
    -  34   +  32  
     import org.owasp.dependencycheck.utils.Settings;
    -  35   +  33  
     import org.owasp.dependencycheck.utils.URLConnectionFactory;
    -  36   +  34  
     import org.owasp.dependencycheck.utils.URLConnectionFailureException;
    +  35   +
     import org.slf4j.Logger;
    +  36   +
     import org.slf4j.LoggerFactory;
     37  
     
     38   @@ -99,7 +99,7 @@
      * @author Jeremy Long
     41  
      */
    -  42  2
     public class EngineVersionCheck implements CachedWebDataSource {
    +  42  16
     public class EngineVersionCheck implements CachedWebDataSource {
     43  
     
     44   @@ -108,7 +108,7 @@
          * Static logger.
     46  
          */
    -  47  1
         private static final Logger LOGGER = Logger.getLogger(EngineVersionCheck.class.getName());
    +  47  8
         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  16
         private CveDB cveDB = null;
     60  
     
     61   @@ -173,8 +173,8 @@
          */
     80  
         protected void setUpdateToVersion(String version) {
    -  81  7
             updateToVersion = version;
    -  82  7
         }
    +  81  31
             updateToVersion = version;
    +  82  31
         }
     83  
     
     84   @@ -184,136 +184,136 @@  86  
             try {
     87  0
                 openDatabase();
    -  88  0
                 LOGGER.fine("Begin Engine Version Check");
    +  88  0
                 LOGGER.debug("Begin Engine Version Check");
     89  0
                 final DatabaseProperties properties = cveDB.getDatabaseProperties();
     90  0
                 final long lastChecked = Long.parseLong(properties.getProperty(ENGINE_VERSION_CHECKED_ON, "0"));
     91  0
                 final long now = (new Date()).getTime();
     92  0
                 updateToVersion = properties.getProperty(CURRENT_ENGINE_RELEASE, "");
     93  0
                 final String currentVersion = Settings.getString(Settings.KEYS.APPLICATION_VERSION, "0.0.0");
    -  94  0
                 LOGGER.fine("Last checked: " + lastChecked);
    -  95  0
                 LOGGER.fine("Now: " + now);
    -  96  0
                 LOGGER.fine("Current version: " + currentVersion);
    +  94  0
                 LOGGER.debug("Last checked: {}", lastChecked);
    +  95  0
                 LOGGER.debug("Now: {}", now);
    +  96  0
                 LOGGER.debug("Current version: {}", currentVersion);
     97  0
                 final boolean updateNeeded = shouldUpdate(lastChecked, now, properties, currentVersion);
     98  0
                 if (updateNeeded) {
    -  99  0
                     final String msg = String.format("A new version of dependency-check is available. Consider updating to version %s.",
    +  99  0
                     LOGGER.warn("A new version of dependency-check is available. Consider updating to version {}.",
     100  
                             updateToVersion);
    -  101  0
                     LOGGER.warning(msg);
    -  102   +  101  
                 }
    -  103  0
             } catch (DatabaseException ex) {
    -  104  0
                 LOGGER.log(Level.FINE, "Database Exception opening databases to retrieve properties", ex);
    -  105  0
                 throw new UpdateException("Error occured updating database properties.");
    -  106   +  102  0
             } catch (DatabaseException ex) {
    +  103  0
                 LOGGER.debug("Database Exception opening databases to retrieve properties", ex);
    +  104  0
                 throw new UpdateException("Error occured updating database properties.");
    +  105  
             } finally {
    -  107  0
                 closeDatabase();
    -  108  0
             }
    -  109  0
         }
    +  106  0
                 closeDatabase();
    +  107  0
             }
    +  108  0
         }
    +  109   +
     
     110   -
     
    +
         /**
     111   -
         /**
    -  112  
          * Determines if a new version of the dependency-check engine has been released.
    +  112   +
          *
     113   -
          *
    -  114  
          * @param lastChecked the epoch time of the last version check
    -  115   +  114  
          * @param now the current epoch time
    -  116   +  115  
          * @param properties the database properties object
    -  117   +  116  
          * @param currentVersion the current version of dependency-check
    -  118   +  117  
          * @return <code>true</code> if a newer version of the database has been released; otherwise <code>false</code>
    +  118   +
          * @throws UpdateException thrown if there is an error connecting to the github documentation site or accessing the local
     119   -
          * @throws UpdateException thrown if there is an error connecting to the github documentation site or accessing the
    +
          * database.
     120   -
          * local database.
    +
          */
     121   -
          */
    -  122  
         protected boolean shouldUpdate(final long lastChecked, final long now, final DatabaseProperties properties,
    -  123   +  122  
                 String currentVersion) throws UpdateException {
    -  124   +  123  
             //check every 30 days if we know there is an update, otherwise check every 7 days
    -  125  7
             int checkRange = 30;
    -  126  7
             if (updateToVersion.isEmpty()) {
    -  127  2
                 checkRange = 7;
    -  128   +  124  31
             int checkRange = 30;
    +  125  31
             if (updateToVersion.isEmpty()) {
    +  126  6
                 checkRange = 7;
    +  127  
             }
    -  129  7
             if (!DateUtil.withinDateRange(lastChecked, now, checkRange)) {
    -  130  2
                 LOGGER.fine("Checking web for new version.");
    -  131  2
                 final String currentRelease = getCurrentReleaseVersion();
    -  132  2
                 if (currentRelease != null) {
    -  133  2
                     final DependencyVersion v = new DependencyVersion(currentRelease);
    -  134  2
                     if (v.getVersionParts() != null && v.getVersionParts().size() >= 3) {
    -  135  2
                         updateToVersion = v.toString();
    -  136  2
                         if (!currentRelease.equals(updateToVersion)) {
    -  137  0
                             properties.save(CURRENT_ENGINE_RELEASE, updateToVersion);
    -  138   +  128  31
             if (!DateUtil.withinDateRange(lastChecked, now, checkRange)) {
    +  129  11
                 LOGGER.debug("Checking web for new version.");
    +  130  11
                 final String currentRelease = getCurrentReleaseVersion();
    +  131  11
                 if (currentRelease != null) {
    +  132  6
                     final DependencyVersion v = new DependencyVersion(currentRelease);
    +  133  6
                     if (v.getVersionParts() != null && v.getVersionParts().size() >= 3) {
    +  134  6
                         updateToVersion = v.toString();
    +  135  6
                         if (!currentRelease.equals(updateToVersion)) {
    +  136  0
                             properties.save(CURRENT_ENGINE_RELEASE, updateToVersion);
    +  137  
                         } else {
    -  139  2
                             properties.save(CURRENT_ENGINE_RELEASE, "");
    -  140   +  138  6
                             properties.save(CURRENT_ENGINE_RELEASE, "");
    +  139  
                         }
    -  141  2
                         properties.save(ENGINE_VERSION_CHECKED_ON, Long.toString(now));
    -  142   +  140  6
                         properties.save(ENGINE_VERSION_CHECKED_ON, Long.toString(now));
    +  141  
                     }
    -  143   +  142  
                 }
    -  144  2
                 LOGGER.log(Level.FINE, "Current Release: {0}", updateToVersion);
    -  145   +  143  11
                 LOGGER.debug("Current Release: {}", updateToVersion);
    +  144  
             }
    -  146  7
             final DependencyVersion running = new DependencyVersion(currentVersion);
    -  147  7
             final DependencyVersion released = new DependencyVersion(updateToVersion);
    -  148  7
             if (running.compareTo(released) < 0) {
    -  149  3
                 LOGGER.fine("Upgrade recommended");
    -  150  3
                 return true;
    -  151   +  145  31
             final DependencyVersion running = new DependencyVersion(currentVersion);
    +  146  31
             final DependencyVersion released = new DependencyVersion(updateToVersion);
    +  147  31
             if (running.compareTo(released) < 0) {
    +  148  9
                 LOGGER.debug("Upgrade recommended");
    +  149  9
                 return true;
    +  150  
             }
    -  152  4
             LOGGER.fine("Upgrade not needed");
    -  153  4
             return false;
    -  154   +  151  22
             LOGGER.debug("Upgrade not needed");
    +  152  22
             return false;
    +  153  
         }
    +  154   +
     
     155   -
     
    +
         /**
     156   -
         /**
    -  157  
          * Opens the CVE and CPE data stores.
    -  158   +  157  
          *
    -  159   +  158  
          * @throws DatabaseException thrown if a data store cannot be opened
    +  159   +
          */
     160   -
          */
    -  161  
         protected final void openDatabase() throws DatabaseException {
    -  162  0
             if (cveDB != null) {
    -  163  0
                 return;
    -  164   +  161  0
             if (cveDB != null) {
    +  162  0
                 return;
    +  163  
             }
    -  165  0
             cveDB = new CveDB();
    -  166  0
             cveDB.open();
    -  167  0
         }
    -  168   +  164  0
             cveDB = new CveDB();
    +  165  0
             cveDB.open();
    +  166  0
         }
    +  167  
     
    -  169   +  168  
         /**
    -  170   +  169  
          * Closes the CVE and CPE data stores.
    -  171   +  170  
          */
    -  172   +  171  
         protected void closeDatabase() {
    -  173  0
             if (cveDB != null) {
    -  174   +  172  0
             if (cveDB != null) {
    +  173  
                 try {
    -  175  0
                     cveDB.close();
    +  174  0
                     cveDB.close();
    +  175  0
                     cveDB = null;
     176  0
                 } catch (Throwable ignore) {
    -  177  0
                     LOGGER.log(Level.FINEST, "Error closing the cveDB", ignore);
    +  177  0
                     LOGGER.trace("Error closing the cveDB", ignore);
     178  0
                 }
     179  
             }
    @@ -332,43 +332,43 @@
          */
     187  
         protected String getCurrentReleaseVersion() {
    -  188  3
             HttpURLConnection conn = null;
    +  188  19
             HttpURLConnection conn = null;
     189  
             try {
    -  190  3
                 final String str = Settings.getString(Settings.KEYS.ENGINE_VERSION_CHECK_URL, "http://jeremylong.github.io/DependencyCheck/current.txt");
    -  191  3
                 final URL url = new URL(str);
    -  192  3
                 conn = URLConnectionFactory.createHttpURLConnection(url);
    -  193  3
                 conn.connect();
    -  194  3
                 if (conn.getResponseCode() != 200) {
    +  190  19
                 final String str = Settings.getString(Settings.KEYS.ENGINE_VERSION_CHECK_URL, "http://jeremylong.github.io/DependencyCheck/current.txt");
    +  191  19
                 final URL url = new URL(str);
    +  192  19
                 conn = URLConnectionFactory.createHttpURLConnection(url);
    +  193  19
                 conn.connect();
    +  194  9
                 if (conn.getResponseCode() != 200) {
     195  0
                     return null;
     196  
                 }
    -  197  3
                 final String releaseVersion = IOUtils.toString(conn.getInputStream(), "UTF-8");
    -  198  3
                 if (releaseVersion != null) {
    -  199  3
                     return releaseVersion.trim();
    +  197  9
                 final String releaseVersion = IOUtils.toString(conn.getInputStream(), "UTF-8");
    +  198  9
                 if (releaseVersion != null) {
    +  199  9
                     return releaseVersion.trim();
     200  
                 }
     201  0
             } catch (MalformedURLException ex) {
    -  202  0
                 LOGGER.log(Level.FINE, "unable to retrieve current release version of dependency-check", ex);
    +  202  0
                 LOGGER.debug("unable to retrieve current release version of dependency-check", ex);
     203  0
             } catch (URLConnectionFailureException ex) {
    -  204  0
                 LOGGER.log(Level.FINE, "unable to retrieve current release version of dependency-check", ex);
    -  205  0
             } catch (IOException ex) {
    -  206  0
                 LOGGER.log(Level.FINE, "unable to retrieve current release version of dependency-check", ex);
    +  204  0
                 LOGGER.debug("unable to retrieve current release version of dependency-check", ex);
    +  205  10
             } catch (IOException ex) {
    +  206  10
                 LOGGER.debug("unable to retrieve current release version of dependency-check", ex);
     207  
             } finally {
    -  208  3
                 if (conn != null) {
    -  209  3
                     conn.disconnect();
    +  208  19
                 if (conn != null) {
    +  209  19
                     conn.disconnect();
     210  
                 }
     211  
             }
    -  212  0
             return null;
    +  212  10
             return null;
     213  
         }
     214  
     }
    - + 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 244e3a19c..1a66c6bee 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 @@ -12,7 +12,7 @@
     
    - +
    Classes in this File Line Coverage Branch Coverage Complexity
    NvdCveUpdater
    0%
    0/15
    0%
    0/4
    5
    NvdCveUpdater
    0%
    0/132
    0%
    0/50
    12.25
     
    @@ -58,84 +58,405 @@  20  
     import java.net.MalformedURLException;
     21   -
     import java.util.logging.Level;
    +
     import java.util.Calendar;
     22   -
     import java.util.logging.Logger;
    +
     import java.util.Date;
     23   -
     import org.owasp.dependencycheck.data.update.exception.UpdateException;
    +
     import java.util.HashSet;
     24   -
     import org.owasp.dependencycheck.utils.DownloadFailedException;
    +
     import java.util.Set;
     25   -
     import org.owasp.dependencycheck.utils.Settings;
    +
     import java.util.concurrent.ExecutionException;
     26   -
     
    +
     import java.util.concurrent.ExecutorService;
     27   -
     /**
    +
     import java.util.concurrent.Executors;
     28   -
      * Class responsible for updating the NVD CVE and CPE data stores.
    +
     import java.util.concurrent.Future;
     29   -
      *
    +
     import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties;
     30   -
      * @author Jeremy Long
    +
     import static org.owasp.dependencycheck.data.nvdcve.DatabaseProperties.MODIFIED;
     31   -
      */
    -  32  0
     public class NvdCveUpdater implements CachedWebDataSource {
    +
     import org.owasp.dependencycheck.data.update.exception.InvalidDataException;
    +  32   +
     import org.owasp.dependencycheck.data.update.exception.UpdateException;
     33   -
     
    +
     import org.owasp.dependencycheck.data.update.nvd.DownloadTask;
     34   -
         /**
    +
     import org.owasp.dependencycheck.data.update.nvd.NvdCveInfo;
     35   -
          * The logger
    +
     import org.owasp.dependencycheck.data.update.nvd.ProcessTask;
     36   -
          */
    -  37  0
         private static final Logger LOGGER = Logger.getLogger(NvdCveUpdater.class.getName());
    +
     import org.owasp.dependencycheck.data.update.nvd.UpdateableNvdCve;
    +  37   +
     import org.owasp.dependencycheck.utils.DateUtil;
     38   -
     
    +
     import org.owasp.dependencycheck.utils.DownloadFailedException;
     39   -
         /**
    +
     import org.owasp.dependencycheck.utils.InvalidSettingException;
     40   -
          * <p>
    +
     import org.owasp.dependencycheck.utils.Settings;
     41   -
          * Downloads the latest NVD CVE XML file from the web and imports it into the current CVE Database.</p>
    +
     import org.slf4j.Logger;
     42   -
          *
    +
     import org.slf4j.LoggerFactory;
     43   -
          * @throws UpdateException is thrown if there is an error updating the database
    +
     
     44   -
          */
    +
     /**
     45   -
         @Override
    +
      * Class responsible for updating the NVD CVE data.
     46   -
         public void update() throws UpdateException {
    +
      *
     47   -
             try {
    -  48  0
                 final StandardUpdate task = new StandardUpdate();
    -  49  0
                 if (task.isUpdateNeeded()) {
    -  50  0
                     task.update();
    +
      * @author Jeremy Long
    +  48   +
      */
    +  49  0
     public class NvdCveUpdater extends BaseUpdater implements CachedWebDataSource {
    +  50   +
     
     51   -
                 }
    -  52  0
             } catch (MalformedURLException ex) {
    -  53  0
                 LOGGER.log(Level.WARNING,
    -  54   -
                         "NVD CVE properties files contain an invalid URL, unable to update the data to use the most current data.");
    -  55  0
                 LOGGER.log(Level.FINE, null, ex);
    -  56  0
             } catch (DownloadFailedException ex) {
    -  57  0
                 LOGGER.log(Level.WARNING,
    -  58   -
                         "Unable to download the NVD CVE data; the results may not include the most recent CPE/CVEs from the NVD.");
    -  59  0
                 if (Settings.getString(Settings.KEYS.PROXY_SERVER) == null) {
    -  60  0
                     LOGGER.log(Level.INFO,
    +
         /**
    +  52   +
          * The logger
    +  53   +
          */
    +  54  0
         private static final Logger LOGGER = LoggerFactory.getLogger(NvdCveUpdater.class);
    +  55   +
         /**
    +  56   +
          * The max thread pool size to use when downloading files.
    +  57   +
          */
    +  58  0
         public static final int MAX_THREAD_POOL_SIZE = Settings.getInt(Settings.KEYS.MAX_DOWNLOAD_THREAD_POOL_SIZE, 3);
    +  59   +
     
    +  60   +
         /**
     61   -
                             "If you are behind a proxy you may need to configure dependency-check to use the proxy.");
    +
          * <p>
     62   -
                 }
    -  63  0
                 LOGGER.log(Level.FINE, null, ex);
    -  64  0
             }
    -  65  0
         }
    +
          * Downloads the latest NVD CVE XML file from the web and imports it into the current CVE Database.</p>
    +  63   +
          *
    +  64   +
          * @throws UpdateException is thrown if there is an error updating the database
    +  65   +
          */
     66   +
         @Override
    +  67   +
         public void update() throws UpdateException {
    +  68   +
             try {
    +  69  0
                 openDataStores();
    +  70  0
                 final UpdateableNvdCve updateable = getUpdatesNeeded();
    +  71  0
                 if (updateable.isUpdateNeeded()) {
    +  72  0
                     performUpdate(updateable);
    +  73   +
                 }
    +  74  0
             } catch (MalformedURLException ex) {
    +  75  0
                 LOGGER.warn(
    +  76   +
                         "NVD CVE properties files contain an invalid URL, unable to update the data to use the most current data.");
    +  77  0
                 LOGGER.debug("", ex);
    +  78  0
             } catch (DownloadFailedException ex) {
    +  79  0
                 LOGGER.warn(
    +  80   +
                         "Unable to download the NVD CVE data; the results may not include the most recent CPE/CVEs from the NVD.");
    +  81  0
                 if (Settings.getString(Settings.KEYS.PROXY_SERVER) == null) {
    +  82  0
                     LOGGER.info(
    +  83   +
                             "If you are behind a proxy you may need to configure dependency-check to use the proxy.");
    +  84   +
                 }
    +  85  0
                 LOGGER.debug("", ex);
    +  86   +
             } finally {
    +  87  0
                 closeDataStores();
    +  88  0
             }
    +  89  0
         }
    +  90   +
     
    +  91   +
         /**
    +  92   +
          * Downloads the latest NVD CVE XML file from the web and imports it into the current CVE Database.
    +  93   +
          *
    +  94   +
          * @param updateable a collection of NVD CVE data file references that need to be downloaded and processed to update the
    +  95   +
          * database
    +  96   +
          * @throws UpdateException is thrown if there is an error updating the database
    +  97   +
          */
    +  98   +
         public void performUpdate(UpdateableNvdCve updateable) throws UpdateException {
    +  99  0
             int maxUpdates = 0;
    +  100   +
             try {
    +  101  0
                 for (NvdCveInfo cve : updateable) {
    +  102  0
                     if (cve.getNeedsUpdate()) {
    +  103  0
                         maxUpdates += 1;
    +  104   +
                     }
    +  105  0
                 }
    +  106  0
                 if (maxUpdates <= 0) {
    +  107   +
                     return;
    +  108   +
                 }
    +  109  0
                 if (maxUpdates > 3) {
    +  110  0
                     LOGGER.info(
    +  111   +
                             "NVD CVE requires several updates; this could take a couple of minutes.");
    +  112   +
                 }
    +  113  0
                 if (maxUpdates > 0) {
    +  114  0
                     openDataStores();
    +  115   +
                 }
    +  116   +
     
    +  117  0
                 final int poolSize = (MAX_THREAD_POOL_SIZE < maxUpdates) ? MAX_THREAD_POOL_SIZE : maxUpdates;
    +  118   +
     
    +  119  0
                 final ExecutorService downloadExecutors = Executors.newFixedThreadPool(poolSize);
    +  120  0
                 final ExecutorService processExecutor = Executors.newSingleThreadExecutor();
    +  121  0
                 final Set<Future<Future<ProcessTask>>> downloadFutures = new HashSet<Future<Future<ProcessTask>>>(maxUpdates);
    +  122  0
                 for (NvdCveInfo cve : updateable) {
    +  123  0
                     if (cve.getNeedsUpdate()) {
    +  124  0
                         final DownloadTask call = new DownloadTask(cve, processExecutor, getCveDB(), Settings.getInstance());
    +  125  0
                         downloadFutures.add(downloadExecutors.submit(call));
    +  126   +
                     }
    +  127  0
                 }
    +  128  0
                 downloadExecutors.shutdown();
    +  129   +
     
    +  130   +
                 //next, move the future future processTasks to just future processTasks
    +  131  0
                 final Set<Future<ProcessTask>> processFutures = new HashSet<Future<ProcessTask>>(maxUpdates);
    +  132  0
                 for (Future<Future<ProcessTask>> future : downloadFutures) {
    +  133  0
                     Future<ProcessTask> task = null;
    +  134   +
                     try {
    +  135  0
                         task = future.get();
    +  136  0
                     } catch (InterruptedException ex) {
    +  137  0
                         downloadExecutors.shutdownNow();
    +  138  0
                         processExecutor.shutdownNow();
    +  139   +
     
    +  140  0
                         LOGGER.debug("Thread was interrupted during download", ex);
    +  141  0
                         throw new UpdateException("The download was interrupted", ex);
    +  142  0
                     } catch (ExecutionException ex) {
    +  143  0
                         downloadExecutors.shutdownNow();
    +  144  0
                         processExecutor.shutdownNow();
    +  145   +
     
    +  146  0
                         LOGGER.debug("Thread was interrupted during download execution", ex);
    +  147  0
                         throw new UpdateException("The execution of the download was interrupted", ex);
    +  148  0
                     }
    +  149  0
                     if (task == null) {
    +  150  0
                         downloadExecutors.shutdownNow();
    +  151  0
                         processExecutor.shutdownNow();
    +  152  0
                         LOGGER.debug("Thread was interrupted during download");
    +  153  0
                         throw new UpdateException("The download was interrupted; unable to complete the update");
    +  154   +
                     } else {
    +  155  0
                         processFutures.add(task);
    +  156   +
                     }
    +  157  0
                 }
    +  158   +
     
    +  159  0
                 for (Future<ProcessTask> future : processFutures) {
    +  160   +
                     try {
    +  161  0
                         final ProcessTask task = future.get();
    +  162  0
                         if (task.getException() != null) {
    +  163  0
                             throw task.getException();
    +  164   +
                         }
    +  165  0
                     } catch (InterruptedException ex) {
    +  166  0
                         processExecutor.shutdownNow();
    +  167  0
                         LOGGER.debug("Thread was interrupted during processing", ex);
    +  168  0
                         throw new UpdateException(ex);
    +  169  0
                     } catch (ExecutionException ex) {
    +  170  0
                         processExecutor.shutdownNow();
    +  171  0
                         LOGGER.debug("Execution Exception during process", ex);
    +  172  0
                         throw new UpdateException(ex);
    +  173   +
                     } finally {
    +  174  0
                         processExecutor.shutdown();
    +  175  0
                     }
    +  176  0
                 }
    +  177   +
     
    +  178  0
                 if (maxUpdates >= 1) { //ensure the modified file date gets written (we may not have actually updated it)
    +  179  0
                     getProperties().save(updateable.get(MODIFIED));
    +  180  0
                     LOGGER.info("Begin database maintenance.");
    +  181  0
                     getCveDB().cleanupDatabase();
    +  182  0
                     LOGGER.info("End database maintenance.");
    +  183   +
                 }
    +  184   +
             } finally {
    +  185  0
                 closeDataStores();
    +  186  0
             }
    +  187  0
         }
    +  188   +
     
    +  189   +
         /**
    +  190   +
          * Determines if the index needs to be updated. This is done by fetching the NVD CVE meta data and checking the last update
    +  191   +
          * date. If the data needs to be refreshed this method will return the NvdCveUrl for the files that need to be updated.
    +  192   +
          *
    +  193   +
          * @return the collection of files that need to be updated
    +  194   +
          * @throws MalformedURLException is thrown if the URL for the NVD CVE Meta data is incorrect
    +  195   +
          * @throws DownloadFailedException is thrown if there is an error. downloading the NVD CVE download data file
    +  196   +
          * @throws UpdateException Is thrown if there is an issue with the last updated properties file
    +  197   +
          */
    +  198   +
         protected final UpdateableNvdCve getUpdatesNeeded() throws MalformedURLException, DownloadFailedException, UpdateException {
    +  199  0
             UpdateableNvdCve updates = null;
    +  200   +
             try {
    +  201  0
                 updates = retrieveCurrentTimestampsFromWeb();
    +  202  0
             } catch (InvalidDataException ex) {
    +  203  0
                 final String msg = "Unable to retrieve valid timestamp from nvd cve downloads page";
    +  204  0
                 LOGGER.debug(msg, ex);
    +  205  0
                 throw new DownloadFailedException(msg, ex);
    +  206  0
             } catch (InvalidSettingException ex) {
    +  207  0
                 LOGGER.debug("Invalid setting found when retrieving timestamps", ex);
    +  208  0
                 throw new DownloadFailedException("Invalid settings", ex);
    +  209  0
             }
    +  210   +
     
    +  211  0
             if (updates == null) {
    +  212  0
                 throw new DownloadFailedException("Unable to retrieve the timestamps of the currently published NVD CVE data");
    +  213   +
             }
    +  214  0
             if (!getProperties().isEmpty()) {
    +  215   +
                 try {
    +  216  0
                     final long lastUpdated = Long.parseLong(getProperties().getProperty(DatabaseProperties.LAST_UPDATED, "0"));
    +  217  0
                     final Date now = new Date();
    +  218  0
                     final int days = Settings.getInt(Settings.KEYS.CVE_MODIFIED_VALID_FOR_DAYS, 7);
    +  219  0
                     if (lastUpdated == updates.getTimeStamp(MODIFIED)) {
    +  220  0
                         updates.clear(); //we don't need to update anything.
    +  221  0
                     } else if (DateUtil.withinDateRange(lastUpdated, now.getTime(), days)) {
    +  222  0
                         for (NvdCveInfo entry : updates) {
    +  223  0
                             if (MODIFIED.equals(entry.getId())) {
    +  224  0
                                 entry.setNeedsUpdate(true);
    +  225   +
                             } else {
    +  226  0
                                 entry.setNeedsUpdate(false);
    +  227   +
                             }
    +  228  0
                         }
    +  229   +
                     } else { //we figure out which of the several XML files need to be downloaded.
    +  230  0
                         for (NvdCveInfo entry : updates) {
    +  231  0
                             if (MODIFIED.equals(entry.getId())) {
    +  232  0
                                 entry.setNeedsUpdate(true);
    +  233   +
                             } else {
    +  234  0
                                 long currentTimestamp = 0;
    +  235   +
                                 try {
    +  236  0
                                     currentTimestamp = Long.parseLong(getProperties().getProperty(DatabaseProperties.LAST_UPDATED_BASE
    +  237   +
                                             + entry.getId(), "0"));
    +  238  0
                                 } catch (NumberFormatException ex) {
    +  239  0
                                     LOGGER.debug("Error parsing '{}' '{}' from nvdcve.lastupdated",
    +  240   +
                                             DatabaseProperties.LAST_UPDATED_BASE, entry.getId(), ex);
    +  241  0
                                 }
    +  242  0
                                 if (currentTimestamp == entry.getTimestamp()) {
    +  243  0
                                     entry.setNeedsUpdate(false);
    +  244   +
                                 }
    +  245   +
                             }
    +  246  0
                         }
    +  247   +
                     }
    +  248  0
                 } catch (NumberFormatException ex) {
    +  249  0
                     LOGGER.warn("An invalid schema version or timestamp exists in the data.properties file.");
    +  250  0
                     LOGGER.debug("", ex);
    +  251  0
                 }
    +  252   +
             }
    +  253  0
             return updates;
    +  254   +
         }
    +  255   +
     
    +  256   +
         /**
    +  257   +
          * Retrieves the timestamps from the NVD CVE meta data file.
    +  258   +
          *
    +  259   +
          * @return the timestamp from the currently published nvdcve downloads page
    +  260   +
          * @throws MalformedURLException thrown if the URL for the NVD CCE Meta data is incorrect.
    +  261   +
          * @throws DownloadFailedException thrown if there is an error downloading the nvd cve meta data file
    +  262   +
          * @throws InvalidDataException thrown if there is an exception parsing the timestamps
    +  263   +
          * @throws InvalidSettingException thrown if the settings are invalid
    +  264   +
          */
    +  265   +
         private UpdateableNvdCve retrieveCurrentTimestampsFromWeb()
    +  266   +
                 throws MalformedURLException, DownloadFailedException, InvalidDataException, InvalidSettingException {
    +  267   +
     
    +  268  0
             final UpdateableNvdCve updates = new UpdateableNvdCve();
    +  269  0
             updates.add(MODIFIED, Settings.getString(Settings.KEYS.CVE_MODIFIED_20_URL),
    +  270   +
                     Settings.getString(Settings.KEYS.CVE_MODIFIED_12_URL),
    +  271   +
                     false);
    +  272   +
     
    +  273  0
             final int start = Settings.getInt(Settings.KEYS.CVE_START_YEAR);
    +  274  0
             final int end = Calendar.getInstance().get(Calendar.YEAR);
    +  275  0
             final String baseUrl20 = Settings.getString(Settings.KEYS.CVE_SCHEMA_2_0);
    +  276  0
             final String baseUrl12 = Settings.getString(Settings.KEYS.CVE_SCHEMA_1_2);
    +  277  0
             for (int i = start; i <= end; i++) {
    +  278  0
                 updates.add(Integer.toString(i), String.format(baseUrl20, i),
    +  279   +
                         String.format(baseUrl12, i),
    +  280   +
                         true);
    +  281   +
             }
    +  282  0
             return updates;
    +  283   +
         }
    +  284   +
     
    +  285  
     }
    - + 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 e2946e689..ca0059812 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 new file mode 100644 index 000000000..346442a10 --- /dev/null +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.cpe.CPEHandler.html @@ -0,0 +1,706 @@ + + + + +Coverage Report + + + + +
    Coverage Report - org.owasp.dependencycheck.data.update.cpe.CPEHandler
    +
     
    + + + + + +
    Classes in this File Line Coverage Branch Coverage Complexity
    CPEHandler
    0%
    0/31
    0%
    0/16
    1.611
    CPEHandler$Element
    0%
    0/17
    N/A
    1.611
    +
     
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
     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) 2015 Jeremy Long. All Rights Reserved.
     17  
      */
     18  
     package org.owasp.dependencycheck.data.update.cpe;
     19  
     
     20  
     import java.io.UnsupportedEncodingException;
     21  
     import java.util.ArrayList;
     22  
     import java.util.List;
     23  
     import org.owasp.dependencycheck.data.update.NvdCveUpdater;
     24  
     import org.owasp.dependencycheck.data.update.exception.InvalidDataException;
     25  
     import org.slf4j.Logger;
     26  
     import org.slf4j.LoggerFactory;
     27  
     import org.xml.sax.Attributes;
     28  
     import org.xml.sax.SAXException;
     29  
     import org.xml.sax.helpers.DefaultHandler;
     30  
     
     31  
     /**
     32  
      * A SAX Handler that will parse the CPE XML and load it into the databse.
     33  
      *
     34  
      * @author Jeremy Long
     35  
      */
     36  0
     public class CPEHandler extends DefaultHandler {
     37  
     
     38  
         /**
     39  
          * The current CPE schema.
     40  
          */
     41  
         private static final String CURRENT_SCHEMA_VERSION = "2.3";
     42  
         /**
     43  
          * The text content of the node being processed. This can be used during the end element event.
     44  
          */
     45  0
         private StringBuilder nodeText = null;
     46  
         /**
     47  
          * A reference to the current element.
     48  
          */
     49  0
         private Element current = new Element();
     50  
         /**
     51  
          * The logger.
     52  
          */
     53  0
         private static final Logger LOGGER = LoggerFactory.getLogger(NvdCveUpdater.class);
     54  
         /**
     55  
          * The list of CPE values.
     56  
          */
     57  0
         private List<Cpe> data = new ArrayList<Cpe>();
     58  
     
     59  
         /**
     60  
          * Returns the list of CPE values.
     61  
          *
     62  
          * @return the list of CPE values
     63  
          */
     64  
         public List<Cpe> getData() {
     65  0
             return data;
     66  
         }
     67  
     
     68  
         /**
     69  
          * Handles the start element event.
     70  
          *
     71  
          * @param uri the elements uri
     72  
          * @param localName the local name
     73  
          * @param qName the qualified name
     74  
          * @param attributes the attributes
     75  
          * @throws SAXException thrown if there is an exception processing the element
     76  
          */
     77  
         @Override
     78  
         public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
     79  0
             nodeText = null;
     80  0
             current.setNode(qName);
     81  0
             if (current.isCpeItemNode()) {
     82  0
                 final String temp = attributes.getValue("deprecated");
     83  0
                 final String value = attributes.getValue("name");
     84  0
                 final boolean delete = "true".equalsIgnoreCase(temp);
     85  0
                 if (!delete && value.startsWith("cpe:/a:") && value.length() > 7) {
     86  
                     try {
     87  0
                         final Cpe cpe = new Cpe(value);
     88  0
                         data.add(cpe);
     89  0
                     } catch (UnsupportedEncodingException ex) {
     90  0
                         LOGGER.debug("Unable to parse the CPE", ex);
     91  0
                     } catch (InvalidDataException ex) {
     92  0
                         LOGGER.debug("CPE is not the correct format", ex);
     93  0
                     }
     94  
                 }
     95  0
             } else if (current.isSchemaVersionNode()) {
     96  0
                 nodeText = new StringBuilder(3);
     97  
             }
     98  
     //        } else if (current.isTitleNode()) {
     99  
     //            //do nothing
     100  
     //        } else if (current.isMetaNode()) {
     101  
     //            //do nothing
     102  
     //        } else if (current.isTimestampNode()) {
     103  
     //            //do nothing
     104  
     //        } else if (current.isCpeListNode()) {
     105  
     //            //do nothing
     106  
     //        } else if (current.isNotesNode()) {
     107  
     //            //do nothing
     108  
     //        } else if (current.isNoteNode()) {
     109  
     //            //do nothing
     110  
     //        } else if (current.isCheckNode()) {
     111  
     //            //do nothing
     112  
     //        } else if (current.isGeneratorNode()) {
     113  
     //            //do nothing
     114  
     //        } else if (current.isProductNameNode()) {
     115  
     //            //do nothing
     116  
     //        } else if (current.isProductVersionNode()) {
     117  
     //            //do nothing
     118  0
         }
     119  
     
     120  
         /**
     121  
          * Reads the characters in the current node.
     122  
          *
     123  
          * @param ch the char array
     124  
          * @param start the start position of the data read
     125  
          * @param length the length of the data read
     126  
          * @throws SAXException thrown if there is an exception processing the characters
     127  
          */
     128  
         @Override
     129  
         public void characters(char[] ch, int start, int length) throws SAXException {
     130  0
             if (nodeText != null) {
     131  0
                 nodeText.append(ch, start, length);
     132  
             }
     133  0
         }
     134  
     
     135  
         /**
     136  
          * Handles the end element event. Stores the CPE data in the Cve Database if the cpe item node is ending.
     137  
          *
     138  
          * @param uri the element's uri
     139  
          * @param localName the local name
     140  
          * @param qName the qualified name
     141  
          * @throws SAXException thrown if there is an exception processing the element
     142  
          */
     143  
         @Override
     144  
         public void endElement(String uri, String localName, String qName) throws SAXException {
     145  0
             current.setNode(qName);
     146  0
             if (current.isSchemaVersionNode() && !CURRENT_SCHEMA_VERSION.equals(nodeText.toString())) {
     147  0
                 throw new SAXException("ERROR: Unexpecgted CPE Schema Version, expected: "
     148  
                         + CURRENT_SCHEMA_VERSION + ", file is: " + nodeText);
     149  
     
     150  
             }
     151  
     //        } else if (current.isCpeItemNode()) {
     152  
     //            //do nothing
     153  
     //        } else if (current.isTitleNode()) {
     154  
     //            //do nothing
     155  
     //        } else if (current.isCpeListNode()) {
     156  
     //            //do nothing
     157  
     //        } else if (current.isMetaNode()) {
     158  
     //            //do nothing
     159  
     //        } else if (current.isNotesNode()) {
     160  
     //            //do nothing
     161  
     //        } else if (current.isNoteNode()) {
     162  
     //            //do nothing
     163  
     //        } else if (current.isCheckNode()) {
     164  
     //            //do nothing
     165  
     //        } else if (current.isGeneratorNode()) {
     166  
     //            //do nothing
     167  
     //        } else if (current.isProductNameNode()) {
     168  
     //            //do nothing
     169  
     //        } else if (current.isProductVersionNode()) {
     170  
     //            //do nothing
     171  
     //        else if (current.isTimestampNode()) {
     172  
     //            //do nothing
     173  
     //        } else {
     174  
     //            throw new SAXException("ERROR STATE: Unexpected qName '" + qName + "'");
     175  
     //        }
     176  0
         }
     177  
     
     178  
         // <editor-fold defaultstate="collapsed" desc="The Element Class that maintains state information about the current node">
     179  
         /**
     180  
          * A simple class to maintain information about the current element while parsing the CPE XML.
     181  
          */
     182  0
         protected class Element {
     183  
     
     184  
             /**
     185  
              * A node type in the CPE Schema 2.2
     186  
              */
     187  
             public static final String CPE_LIST = "cpe-list";
     188  
             /**
     189  
              * A node type in the CPE Schema 2.2
     190  
              */
     191  
             public static final String CPE_ITEM = "cpe-item";
     192  
             /**
     193  
              * A node type in the CPE Schema 2.2
     194  
              */
     195  
             public static final String TITLE = "title";
     196  
             /**
     197  
              * A node type in the CPE Schema 2.2
     198  
              */
     199  
             public static final String NOTES = "notes";
     200  
             /**
     201  
              * A node type in the CPE Schema 2.2
     202  
              */
     203  
             public static final String NOTE = "note";
     204  
             /**
     205  
              * A node type in the CPE Schema 2.2
     206  
              */
     207  
             public static final String CHECK = "check";
     208  
             /**
     209  
              * A node type in the CPE Schema 2.2
     210  
              */
     211  
             public static final String META = "meta:item-metadata";
     212  
             /**
     213  
              * A node type in the CPE Schema 2.2
     214  
              */
     215  
             public static final String GENERATOR = "generator";
     216  
             /**
     217  
              * A node type in the CPE Schema 2.2
     218  
              */
     219  
             public static final String PRODUCT_NAME = "product_name";
     220  
             /**
     221  
              * A node type in the CPE Schema 2.2
     222  
              */
     223  
             public static final String PRODUCT_VERSION = "product_version";
     224  
             /**
     225  
              * A node type in the CPE Schema 2.2
     226  
              */
     227  
             public static final String SCHEMA_VERSION = "schema_version";
     228  
             /**
     229  
              * A node type in the CPE Schema 2.2
     230  
              */
     231  
             public static final String TIMESTAMP = "timestamp";
     232  
             /**
     233  
              * A reference to the current node.
     234  
              */
     235  0
             private String node = null;
     236  
     
     237  
             /**
     238  
              * Gets the value of node
     239  
              *
     240  
              * @return the value of node
     241  
              */
     242  
             public String getNode() {
     243  0
                 return this.node;
     244  
             }
     245  
     
     246  
             /**
     247  
              * Sets the value of node
     248  
              *
     249  
              * @param node new value of node
     250  
              */
     251  
             public void setNode(String node) {
     252  0
                 this.node = node;
     253  0
             }
     254  
     
     255  
             /**
     256  
              * Checks if the handler is at the CPE_LIST node
     257  
              *
     258  
              * @return true or false
     259  
              */
     260  
             public boolean isCpeListNode() {
     261  0
                 return CPE_LIST.equals(node);
     262  
             }
     263  
     
     264  
             /**
     265  
              * Checks if the handler is at the CPE_ITEM node
     266  
              *
     267  
              * @return true or false
     268  
              */
     269  
             public boolean isCpeItemNode() {
     270  0
                 return CPE_ITEM.equals(node);
     271  
             }
     272  
     
     273  
             /**
     274  
              * Checks if the handler is at the TITLE node
     275  
              *
     276  
              * @return true or false
     277  
              */
     278  
             public boolean isTitleNode() {
     279  0
                 return TITLE.equals(node);
     280  
             }
     281  
     
     282  
             /**
     283  
              * Checks if the handler is at the NOTES node
     284  
              *
     285  
              * @return true or false
     286  
              */
     287  
             public boolean isNotesNode() {
     288  0
                 return NOTES.equals(node);
     289  
             }
     290  
     
     291  
             /**
     292  
              * Checks if the handler is at the NOTE node
     293  
              *
     294  
              * @return true or false
     295  
              */
     296  
             public boolean isNoteNode() {
     297  0
                 return NOTE.equals(node);
     298  
             }
     299  
     
     300  
             /**
     301  
              * Checks if the handler is at the CHECK node
     302  
              *
     303  
              * @return true or false
     304  
              */
     305  
             public boolean isCheckNode() {
     306  0
                 return CHECK.equals(node);
     307  
             }
     308  
     
     309  
             /**
     310  
              * Checks if the handler is at the META node
     311  
              *
     312  
              * @return true or false
     313  
              */
     314  
             public boolean isMetaNode() {
     315  0
                 return META.equals(node);
     316  
             }
     317  
     
     318  
             /**
     319  
              * Checks if the handler is at the GENERATOR node
     320  
              *
     321  
              * @return true or false
     322  
              */
     323  
             public boolean isGeneratorNode() {
     324  0
                 return GENERATOR.equals(node);
     325  
             }
     326  
     
     327  
             /**
     328  
              * Checks if the handler is at the PRODUCT_NAME node
     329  
              *
     330  
              * @return true or false
     331  
              */
     332  
             public boolean isProductNameNode() {
     333  0
                 return PRODUCT_NAME.equals(node);
     334  
             }
     335  
     
     336  
             /**
     337  
              * Checks if the handler is at the PRODUCT_VERSION node
     338  
              *
     339  
              * @return true or false
     340  
              */
     341  
             public boolean isProductVersionNode() {
     342  0
                 return PRODUCT_VERSION.equals(node);
     343  
             }
     344  
     
     345  
             /**
     346  
              * Checks if the handler is at the SCHEMA_VERSION node
     347  
              *
     348  
              * @return true or false
     349  
              */
     350  
             public boolean isSchemaVersionNode() {
     351  0
                 return SCHEMA_VERSION.equals(node);
     352  
             }
     353  
     
     354  
             /**
     355  
              * Checks if the handler is at the TIMESTAMP node
     356  
              *
     357  
              * @return true or false
     358  
              */
     359  
             public boolean isTimestampNode() {
     360  0
                 return TIMESTAMP.equals(node);
     361  
             }
     362  
         }
     363  
         // </editor-fold>
     364  
     }
    + + + + 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 new file mode 100644 index 000000000..dc32692b6 --- /dev/null +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.cpe.Cpe.html @@ -0,0 +1,256 @@ + + + + +Coverage Report + + + + +
    Coverage Report - org.owasp.dependencycheck.data.update.cpe.Cpe
    +
     
    + + + + +
    Classes in this File Line Coverage Branch Coverage Complexity
    Cpe
    0%
    0/18
    0%
    0/2
    1.25
    +
     
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
     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) 2015 Jeremy Long. All Rights Reserved.
     17  
      */
     18  
     package org.owasp.dependencycheck.data.update.cpe;
     19  
     
     20  
     import java.io.UnsupportedEncodingException;
     21  
     import java.net.URLDecoder;
     22  
     import org.owasp.dependencycheck.data.update.exception.InvalidDataException;
     23  
     
     24  
     /**
     25  
      *
     26  
      * @author Jeremy Long
     27  
      */
     28  
     public class Cpe {
     29  
     
     30  
         /**
     31  
          * Constructs a new Cpe Object by parsing the vendor and product from the CPE identifier value.
     32  
          *
     33  
          * @param value the cpe identifier (cpe:/a:vendor:product:version:....)
     34  
          * @throws UnsupportedEncodingException thrown if UTF-8 is not supported
     35  
          * @throws InvalidDataException thrown if the CPE provided is not the correct format
     36  
          */
     37  0
         public Cpe(String value) throws UnsupportedEncodingException, InvalidDataException {
     38  0
             this.value = value;
     39  0
             final String[] data = value.substring(7).split(":");
     40  0
             if (data.length >= 2) {
     41  0
                 vendor = URLDecoder.decode(data[0].replace("+", "%2B"), "UTF-8");
     42  0
                 product = URLDecoder.decode(data[1].replace("+", "%2B"), "UTF-8");
     43  
             } else {
     44  0
                 throw new InvalidDataException(String.format("CPE has an invalid format: %s", value));
     45  
             }
     46  0
         }
     47  
     
     48  
         /**
     49  
          * The CPE identifier string (cpe:/a:vendor:product:version).
     50  
          */
     51  
         private String value;
     52  
     
     53  
         /**
     54  
          * Get the value of value.
     55  
          *
     56  
          * @return the value of value
     57  
          */
     58  
         public String getValue() {
     59  0
             return value;
     60  
         }
     61  
     
     62  
         /**
     63  
          * Set the value of value.
     64  
          *
     65  
          * @param value new value of value
     66  
          */
     67  
         public void setValue(String value) {
     68  0
             this.value = value;
     69  0
         }
     70  
         /**
     71  
          * The vendor portion of the identifier.
     72  
          */
     73  
         private String vendor;
     74  
     
     75  
         /**
     76  
          * Get the value of vendor.
     77  
          *
     78  
          * @return the value of vendor
     79  
          */
     80  
         public String getVendor() {
     81  0
             return vendor;
     82  
         }
     83  
     
     84  
         /**
     85  
          * Set the value of vendor.
     86  
          *
     87  
          * @param vendor new value of vendor
     88  
          */
     89  
         public void setVendor(String vendor) {
     90  0
             this.vendor = vendor;
     91  0
         }
     92  
     
     93  
         /**
     94  
          * The product portion of the identifier.
     95  
          */
     96  
         private String product;
     97  
     
     98  
         /**
     99  
          * Get the value of product.
     100  
          *
     101  
          * @return the value of product
     102  
          */
     103  
         public String getProduct() {
     104  0
             return product;
     105  
         }
     106  
     
     107  
         /**
     108  
          * Set the value of product.
     109  
          *
     110  
          * @param product new value of product
     111  
          */
     112  
         public void setProduct(String product) {
     113  0
             this.product = product;
     114  0
         }
     115  
     
     116  
         /**
     117  
          * Returns the full CPE identifier.
     118  
          *
     119  
          * @return the full CPE identifier
     120  
          */
     121  
         @Override
     122  
         public String toString() {
     123  0
             return value;
     124  
         }
     125  
     }
    + + + + 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 f97aab9e3..48c6ddade 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 f014f917a..6573d851f 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 new file mode 100644 index 000000000..256067208 --- /dev/null +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.DownloadTask.html @@ -0,0 +1,529 @@ + + + + +Coverage Report + + + + +
    Coverage Report - org.owasp.dependencycheck.data.update.nvd.DownloadTask
    +
     
    + + + + +
    Classes in this File Line Coverage Branch Coverage Complexity
    DownloadTask
    59%
    55/93
    25%
    11/44
    3.583
    +
     
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
     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.data.update.nvd;
     19  
     
     20  
     import java.io.File;
     21  
     import java.io.FileInputStream;
     22  
     import java.io.FileNotFoundException;
     23  
     import java.io.FileOutputStream;
     24  
     import java.io.IOException;
     25  
     import java.net.URL;
     26  
     import java.util.concurrent.Callable;
     27  
     import java.util.concurrent.ExecutorService;
     28  
     import java.util.concurrent.Future;
     29  
     import java.util.zip.GZIPInputStream;
     30  
     import org.apache.commons.io.FileUtils;
     31  
     import org.owasp.dependencycheck.data.nvdcve.CveDB;
     32  
     import org.owasp.dependencycheck.data.update.exception.UpdateException;
     33  
     import org.owasp.dependencycheck.utils.DownloadFailedException;
     34  
     import org.owasp.dependencycheck.utils.Downloader;
     35  
     import org.owasp.dependencycheck.utils.Settings;
     36  
     import org.slf4j.Logger;
     37  
     import org.slf4j.LoggerFactory;
     38  
     
     39  
     /**
     40  
      * A callable object to download two files.
     41  
      *
     42  
      * @author Jeremy Long
     43  
      */
     44  0
     public class DownloadTask implements Callable<Future<ProcessTask>> {
     45  
     
     46  
         /**
     47  
          * The Logger.
     48  
          */
     49  8
         private static final Logger LOGGER = LoggerFactory.getLogger(DownloadTask.class);
     50  
     
     51  
         /**
     52  
          * Simple constructor for the callable download task.
     53  
          *
     54  
          * @param nvdCveInfo the NVD CVE info
     55  
          * @param processor the processor service to submit the downloaded files to
     56  
          * @param cveDB the CVE DB to use to store the vulnerability data
     57  
          * @param settings a reference to the global settings object; this is necessary so that when the thread is started the
     58  
          * dependencies have a correct reference to the global settings.
     59  
          * @throws UpdateException thrown if temporary files could not be created
     60  
          */
     61  8
         public DownloadTask(NvdCveInfo nvdCveInfo, ExecutorService processor, CveDB cveDB, Settings settings) throws UpdateException {
     62  8
             this.nvdCveInfo = nvdCveInfo;
     63  8
             this.processorService = processor;
     64  8
             this.cveDB = cveDB;
     65  8
             this.settings = settings;
     66  
     
     67  
             final File file1;
     68  
             final File file2;
     69  
     
     70  
             try {
     71  8
                 file1 = File.createTempFile("cve" + nvdCveInfo.getId() + "_", ".xml", Settings.getTempDirectory());
     72  8
                 file2 = File.createTempFile("cve_1_2_" + nvdCveInfo.getId() + "_", ".xml", Settings.getTempDirectory());
     73  0
             } catch (IOException ex) {
     74  0
                 throw new UpdateException("Unable to create temporary files", ex);
     75  8
             }
     76  8
             this.first = file1;
     77  8
             this.second = file2;
     78  
     
     79  8
         }
     80  
         /**
     81  
          * The CVE DB to use when processing the files.
     82  
          */
     83  
         private CveDB cveDB;
     84  
         /**
     85  
          * The processor service to pass the results of the download to.
     86  
          */
     87  
         private ExecutorService processorService;
     88  
         /**
     89  
          * The NVD CVE Meta Data.
     90  
          */
     91  
         private NvdCveInfo nvdCveInfo;
     92  
         /**
     93  
          * A reference to the global settings object.
     94  
          */
     95  
         private Settings settings;
     96  
     
     97  
         /**
     98  
          * Get the value of nvdCveInfo.
     99  
          *
     100  
          * @return the value of nvdCveInfo
     101  
          */
     102  
         public NvdCveInfo getNvdCveInfo() {
     103  0
             return nvdCveInfo;
     104  
         }
     105  
     
     106  
         /**
     107  
          * Set the value of nvdCveInfo.
     108  
          *
     109  
          * @param nvdCveInfo new value of nvdCveInfo
     110  
          */
     111  
         public void setNvdCveInfo(NvdCveInfo nvdCveInfo) {
     112  0
             this.nvdCveInfo = nvdCveInfo;
     113  0
         }
     114  
         /**
     115  
          * a file.
     116  
          */
     117  
         private File first;
     118  
     
     119  
         /**
     120  
          * Get the value of first.
     121  
          *
     122  
          * @return the value of first
     123  
          */
     124  
         public File getFirst() {
     125  0
             return first;
     126  
         }
     127  
     
     128  
         /**
     129  
          * Set the value of first.
     130  
          *
     131  
          * @param first new value of first
     132  
          */
     133  
         public void setFirst(File first) {
     134  0
             this.first = first;
     135  0
         }
     136  
         /**
     137  
          * a file.
     138  
          */
     139  
         private File second;
     140  
     
     141  
         /**
     142  
          * Get the value of second.
     143  
          *
     144  
          * @return the value of second
     145  
          */
     146  
         public File getSecond() {
     147  0
             return second;
     148  
         }
     149  
     
     150  
         /**
     151  
          * Set the value of second.
     152  
          *
     153  
          * @param second new value of second
     154  
          */
     155  
         public void setSecond(File second) {
     156  0
             this.second = second;
     157  0
         }
     158  
         /**
     159  
          * A placeholder for an exception.
     160  
          */
     161  8
         private Exception exception = null;
     162  
     
     163  
         /**
     164  
          * Get the value of exception.
     165  
          *
     166  
          * @return the value of exception
     167  
          */
     168  
         public Exception getException() {
     169  0
             return exception;
     170  
         }
     171  
     
     172  
         /**
     173  
          * returns whether or not an exception occurred during download.
     174  
          *
     175  
          * @return whether or not an exception occurred during download
     176  
          */
     177  
         public boolean hasException() {
     178  0
             return exception != null;
     179  
         }
     180  
     
     181  
         @Override
     182  
         public Future<ProcessTask> call() throws Exception {
     183  
             try {
     184  8
                 Settings.setInstance(settings);
     185  8
                 final URL url1 = new URL(nvdCveInfo.getUrl());
     186  8
                 final URL url2 = new URL(nvdCveInfo.getOldSchemaVersionUrl());
     187  8
                 LOGGER.info("Download Started for NVD CVE - {}", nvdCveInfo.getId());
     188  
                 try {
     189  8
                     Downloader.fetchFile(url1, first);
     190  3
                     Downloader.fetchFile(url2, second);
     191  5
                 } catch (DownloadFailedException ex) {
     192  5
                     LOGGER.warn("Download Failed for NVD CVE - {}\nSome CVEs may not be reported.", nvdCveInfo.getId());
     193  5
                     if (Settings.getString(Settings.KEYS.PROXY_SERVER) == null) {
     194  5
                         LOGGER.info(
     195  
                                 "If you are behind a proxy you may need to configure dependency-check to use the proxy.");
     196  
                     }
     197  5
                     LOGGER.debug("", ex);
     198  5
                     return null;
     199  3
                 }
     200  3
                 if (url1.toExternalForm().endsWith(".xml.gz")) {
     201  3
                     extractGzip(first);
     202  
                 }
     203  3
                 if (url2.toExternalForm().endsWith(".xml.gz")) {
     204  3
                     extractGzip(second);
     205  
                 }
     206  
     
     207  3
                 LOGGER.info("Download Complete for NVD CVE - {}", nvdCveInfo.getId());
     208  3
                 if (this.processorService == null) {
     209  3
                     return null;
     210  
                 }
     211  0
                 final ProcessTask task = new ProcessTask(cveDB, this, settings);
     212  0
                 return this.processorService.submit(task);
     213  
     
     214  0
             } catch (Throwable ex) {
     215  0
                 LOGGER.warn("An exception occurred downloading NVD CVE - {}\nSome CVEs may not be reported.", nvdCveInfo.getId());
     216  0
                 LOGGER.debug("Download Task Failed", ex);
     217  
             } finally {
     218  8
                 Settings.cleanup(false);
     219  0
             }
     220  0
             return null;
     221  
         }
     222  
     
     223  
         /**
     224  
          * Attempts to delete the files that were downloaded.
     225  
          */
     226  
         public void cleanup() {
     227  0
             boolean deleted = false;
     228  
             try {
     229  0
                 if (first != null && first.exists()) {
     230  0
                     deleted = first.delete();
     231  
                 }
     232  
             } finally {
     233  0
                 if (first != null && (first.exists() || !deleted)) {
     234  0
                     first.deleteOnExit();
     235  
                 }
     236  
             }
     237  
             try {
     238  0
                 deleted = false;
     239  0
                 if (second != null && second.exists()) {
     240  0
                     deleted = second.delete();
     241  
                 }
     242  
             } finally {
     243  0
                 if (second != null && (second.exists() || !deleted)) {
     244  0
                     second.deleteOnExit();
     245  
                 }
     246  
             }
     247  0
         }
     248  
     
     249  
         /**
     250  
          * Extracts the file contained in a gzip archive. The extracted file is placed in the exact same path as the file specified.
     251  
          *
     252  
          * @param file the archive file
     253  
          * @throws FileNotFoundException thrown if the file does not exist
     254  
          * @throws IOException thrown if there is an error extracting the file.
     255  
          */
     256  
         private void extractGzip(File file) throws FileNotFoundException, IOException {
     257  6
             final String originalPath = file.getPath();
     258  6
             final File gzip = new File(originalPath + ".gz");
     259  6
             if (gzip.isFile() && !gzip.delete()) {
     260  0
                 gzip.deleteOnExit();
     261  
             }
     262  6
             if (!file.renameTo(gzip)) {
     263  0
                 throw new IOException("Unable to rename '" + file.getPath() + "'");
     264  
             }
     265  6
             final File newfile = new File(originalPath);
     266  
     
     267  6
             final byte[] buffer = new byte[4096];
     268  
     
     269  6
             GZIPInputStream cin = null;
     270  6
             FileOutputStream out = null;
     271  
             try {
     272  6
                 cin = new GZIPInputStream(new FileInputStream(gzip));
     273  6
                 out = new FileOutputStream(newfile);
     274  
     
     275  
                 int len;
     276  1767
                 while ((len = cin.read(buffer)) > 0) {
     277  1761
                     out.write(buffer, 0, len);
     278  
                 }
     279  
             } finally {
     280  6
                 if (cin != null) {
     281  
                     try {
     282  6
                         cin.close();
     283  0
                     } catch (IOException ex) {
     284  0
                         LOGGER.trace("ignore", ex);
     285  6
                     }
     286  
                 }
     287  6
                 if (out != null) {
     288  
                     try {
     289  6
                         out.close();
     290  0
                     } catch (IOException ex) {
     291  0
                         LOGGER.trace("ignore", ex);
     292  6
                     }
     293  
                 }
     294  6
                 if (gzip.isFile()) {
     295  6
                     FileUtils.deleteQuietly(gzip);
     296  
                 }
     297  
             }
     298  6
         }
     299  
     }
    + + + + 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 new file mode 100644 index 000000000..c1afc30b3 --- /dev/null +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.NvdCve12Handler.html @@ -0,0 +1,454 @@ + + + + +Coverage Report + + + + +
    Coverage Report - org.owasp.dependencycheck.data.update.nvd.NvdCve12Handler
    +
     
    + + + + + +
    Classes in this File Line Coverage Branch Coverage Complexity
    NvdCve12Handler
    95%
    47/49
    86%
    26/30
    2.6
    NvdCve12Handler$Element
    77%
    7/9
    N/A
    2.6
    +
     
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
     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) 2012 Jeremy Long. All Rights Reserved.
     17  
      */
     18  
     package org.owasp.dependencycheck.data.update.nvd;
     19  
     
     20  
     import java.util.ArrayList;
     21  
     import java.util.HashMap;
     22  
     import java.util.List;
     23  
     import java.util.Map;
     24  
     import org.owasp.dependencycheck.dependency.VulnerableSoftware;
     25  
     import org.xml.sax.Attributes;
     26  
     import org.xml.sax.SAXException;
     27  
     import org.xml.sax.SAXNotSupportedException;
     28  
     import org.xml.sax.helpers.DefaultHandler;
     29  
     
     30  
     /**
     31  
      * A SAX Handler that will parse the NVD CVE XML (schema version 1.2). This parses the xml and retrieves a listing of
     32  
      * CPEs that have previous versions specified. The previous version information is not in the 2.0 version of the schema
     33  
      * and is useful to ensure accurate identification (or at least complete).
     34  
      *
     35  
      * @author Jeremy Long
     36  
      */
     37  8
     public class NvdCve12Handler extends DefaultHandler {
     38  
     
     39  
         /**
     40  
          * the supported schema version.
     41  
          */
     42  
         private static final String CURRENT_SCHEMA_VERSION = "1.2";
     43  
         /**
     44  
          * the current vulnerability.
     45  
          */
     46  
         private String vulnerability;
     47  
         /**
     48  
          * a list of vulnerable software.
     49  
          */
     50  
         private List<VulnerableSoftware> software;
     51  
         /**
     52  
          * the vendor name.
     53  
          */
     54  
         private String vendor;
     55  
         /**
     56  
          * the product name.
     57  
          */
     58  
         private String product;
     59  
         /**
     60  
          * if the nvd cve should be skipped because it was rejected.
     61  
          */
     62  8
         private boolean skip = false;
     63  
         /**
     64  
          * flag indicating if there is a previous version.
     65  
          */
     66  8
         private boolean hasPreviousVersion = false;
     67  
         /**
     68  
          * The current element.
     69  
          */
     70  8
         private final Element current = new Element();
     71  
         /**
     72  
          * a map of vulnerabilities.
     73  
          */
     74  
         private Map<String, List<VulnerableSoftware>> vulnerabilities;
     75  
     
     76  
         /**
     77  
          * Get the value of vulnerabilities.
     78  
          *
     79  
          * @return the value of vulnerabilities
     80  
          */
     81  
         public Map<String, List<VulnerableSoftware>> getVulnerabilities() {
     82  8
             return vulnerabilities;
     83  
         }
     84  
     
     85  
         @Override
     86  
         public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
     87  9776
             current.setNode(qName);
     88  9776
             if (current.isEntryNode()) {
     89  216
                 vendor = null;
     90  216
                 product = null;
     91  216
                 hasPreviousVersion = false;
     92  216
                 final String reject = attributes.getValue("reject");
     93  216
                 skip = "1".equals(reject);
     94  216
                 if (!skip) {
     95  208
                     vulnerability = attributes.getValue("name");
     96  208
                     software = new ArrayList<VulnerableSoftware>();
     97  
                 } else {
     98  8
                     vulnerability = null;
     99  8
                     software = null;
     100  
                 }
     101  216
             } else if (!skip && current.isProdNode()) {
     102  
     
     103  416
                 vendor = attributes.getValue("vendor");
     104  416
                 product = attributes.getValue("name");
     105  9144
             } else if (!skip && current.isVersNode()) {
     106  6088
                 final String prev = attributes.getValue("prev");
     107  6088
                 if (prev != null && "1".equals(prev)) {
     108  8
                     hasPreviousVersion = true;
     109  8
                     final String edition = attributes.getValue("edition");
     110  8
                     final String num = attributes.getValue("num");
     111  
     
     112  
                     /*yes yes, this may not actually be an "a" - it could be an OS, etc. but for our
     113  
                      purposes this is good enough as we won't use this if we don't find a corresponding "a"
     114  
                      in the nvd cve 2.0. */
     115  8
                     String cpe = "cpe:/a:" + vendor + ":" + product;
     116  8
                     if (num != null) {
     117  8
                         cpe += ":" + num;
     118  
                     }
     119  8
                     if (edition != null) {
     120  0
                         cpe += ":" + edition;
     121  
                     }
     122  8
                     final VulnerableSoftware vs = new VulnerableSoftware();
     123  8
                     vs.setCpe(cpe);
     124  8
                     vs.setPreviousVersion(prev);
     125  8
                     software.add(vs);
     126  
                 }
     127  6088
             } else if (current.isNVDNode()) {
     128  8
                 final String nvdVer = attributes.getValue("nvd_xml_version");
     129  8
                 if (!CURRENT_SCHEMA_VERSION.equals(nvdVer)) {
     130  0
                     throw new SAXNotSupportedException("Schema version " + nvdVer + " is not supported");
     131  
                 }
     132  8
                 vulnerabilities = new HashMap<String, List<VulnerableSoftware>>();
     133  
             }
     134  9776
         }
     135  
     
     136  
         @Override
     137  
         public void endElement(String uri, String localName, String qName) throws SAXException {
     138  9776
             current.setNode(qName);
     139  9776
             if (current.isEntryNode()) {
     140  216
                 if (!skip && hasPreviousVersion) {
     141  8
                     vulnerabilities.put(vulnerability, software);
     142  
                 }
     143  216
                 vulnerability = null;
     144  216
                 software = null;
     145  
             }
     146  9776
         }
     147  
     
     148  
         // <editor-fold defaultstate="collapsed" desc="The Element Class that maintains state information about the current node">
     149  
         /**
     150  
          * A simple class to maintain information about the current element while parsing the NVD CVE XML.
     151  
          */
     152  8
         protected static class Element {
     153  
     
     154  
             /**
     155  
              * A node type in the NVD CVE Schema 1.2.
     156  
              */
     157  
             public static final String NVD = "nvd";
     158  
             /**
     159  
              * A node type in the NVD CVE Schema 1.2.
     160  
              */
     161  
             public static final String ENTRY = "entry";
     162  
             /**
     163  
              * A node type in the NVD CVE Schema 1.2.
     164  
              */
     165  
             public static final String VULN_SOFTWARE = "vuln_soft";
     166  
             /**
     167  
              * A node type in the NVD CVE Schema 1.2.
     168  
              */
     169  
             public static final String PROD = "prod";
     170  
             /**
     171  
              * A node type in the NVD CVE Schema 1.2.
     172  
              */
     173  
             public static final String VERS = "vers";
     174  
             /**
     175  
              * The name of the current node.
     176  
              */
     177  
             private String node;
     178  
     
     179  
             /**
     180  
              * Gets the value of node.
     181  
              *
     182  
              * @return the value of node
     183  
              */
     184  
             public String getNode() {
     185  0
                 return this.node;
     186  
             }
     187  
     
     188  
             /**
     189  
              * Sets the value of node.
     190  
              *
     191  
              * @param node new value of node
     192  
              */
     193  
             public void setNode(String node) {
     194  19552
                 this.node = node;
     195  19552
             }
     196  
     
     197  
             /**
     198  
              * Checks if the handler is at the NVD node.
     199  
              *
     200  
              * @return true or false
     201  
              */
     202  
             public boolean isNVDNode() {
     203  3056
                 return NVD.equals(node);
     204  
             }
     205  
     
     206  
             /**
     207  
              * Checks if the handler is at the ENTRY node.
     208  
              *
     209  
              * @return true or false
     210  
              */
     211  
             public boolean isEntryNode() {
     212  19552
                 return ENTRY.equals(node);
     213  
             }
     214  
     
     215  
             /**
     216  
              * Checks if the handler is at the VULN_SOFTWARE node.
     217  
              *
     218  
              * @return true or false
     219  
              */
     220  
             public boolean isVulnSoftwareNode() {
     221  0
                 return VULN_SOFTWARE.equals(node);
     222  
             }
     223  
     
     224  
             /**
     225  
              * Checks if the handler is at the PROD node.
     226  
              *
     227  
              * @return true or false
     228  
              */
     229  
             public boolean isProdNode() {
     230  9536
                 return PROD.equals(node);
     231  
             }
     232  
     
     233  
             /**
     234  
              * Checks if the handler is at the VERS node.
     235  
              *
     236  
              * @return true or false
     237  
              */
     238  
             public boolean isVersNode() {
     239  9120
                 return VERS.equals(node);
     240  
             }
     241  
         }
     242  
         // </editor-fold>
     243  
     }
    + + + + 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 new file mode 100644 index 000000000..831821632 --- /dev/null +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.NvdCve20Handler.html @@ -0,0 +1,872 @@ + + + + +Coverage Report + + + + +
    Coverage Report - org.owasp.dependencycheck.data.update.nvd.NvdCve20Handler
    +
     
    + + + + + +
    Classes in this File Line Coverage Branch Coverage Complexity
    NvdCve20Handler
    80%
    100/125
    89%
    75/84
    3.04
    NvdCve20Handler$Element
    94%
    18/19
    N/A
    3.04
    +
     
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
     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) 2012 Jeremy Long. All Rights Reserved.
     17  
      */
     18  
     package org.owasp.dependencycheck.data.update.nvd;
     19  
     
     20  
     import java.io.IOException;
     21  
     import java.util.List;
     22  
     import java.util.Map;
     23  
     import org.apache.lucene.index.CorruptIndexException;
     24  
     import org.owasp.dependencycheck.data.nvdcve.CveDB;
     25  
     import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
     26  
     import org.owasp.dependencycheck.dependency.Reference;
     27  
     import org.owasp.dependencycheck.dependency.Vulnerability;
     28  
     import org.owasp.dependencycheck.dependency.VulnerableSoftware;
     29  
     import org.slf4j.Logger;
     30  
     import org.slf4j.LoggerFactory;
     31  
     import org.xml.sax.Attributes;
     32  
     import org.xml.sax.SAXException;
     33  
     import org.xml.sax.SAXNotSupportedException;
     34  
     import org.xml.sax.helpers.DefaultHandler;
     35  
     
     36  
     /**
     37  
      * A SAX Handler that will parse the NVD CVE XML (schema version 2.0).
     38  
      *
     39  
      * @author Jeremy Long
     40  
      */
     41  8
     public class NvdCve20Handler extends DefaultHandler {
     42  
     
     43  
         /**
     44  
          * The logger.
     45  
          */
     46  8
         private static final Logger LOGGER = LoggerFactory.getLogger(NvdCve20Handler.class);
     47  
         /**
     48  
          * the current supported schema version.
     49  
          */
     50  
         private static final String CURRENT_SCHEMA_VERSION = "2.0";
     51  
         /**
     52  
          * the current element.
     53  
          */
     54  8
         private final Element current = new Element();
     55  
         /**
     56  
          * the text of the node.
     57  
          */
     58  
         private StringBuilder nodeText;
     59  
         /**
     60  
          * the vulnerability.
     61  
          */
     62  
         private Vulnerability vulnerability;
     63  
         /**
     64  
          * a reference for the cve.
     65  
          */
     66  
         private Reference reference;
     67  
         /**
     68  
          * flag indicating whether the application has a cpe.
     69  
          */
     70  8
         private boolean hasApplicationCpe = false;
     71  
         /**
     72  
          * The total number of entries parsed.
     73  
          */
     74  
         private int totalNumberOfEntries;
     75  
     
     76  
         /**
     77  
          * Get the value of totalNumberOfEntries.
     78  
          *
     79  
          * @return the value of totalNumberOfEntries
     80  
          */
     81  
         public int getTotalNumberOfEntries() {
     82  0
             return totalNumberOfEntries;
     83  
         }
     84  
         /**
     85  
          * The total number of application entries parsed.
     86  
          */
     87  
         private int totalNumberOfApplicationEntries;
     88  
     
     89  
         /**
     90  
          * Get the value of totalNumberOfApplicationEntries.
     91  
          *
     92  
          * @return the value of totalNumberOfApplicationEntries
     93  
          */
     94  
         public int getTotalNumberOfApplicationEntries() {
     95  0
             return totalNumberOfApplicationEntries;
     96  
         }
     97  
     
     98  
         @Override
     99  
         public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
     100  19296
             current.setNode(qName);
     101  19296
             if (current.isEntryNode()) {
     102  216
                 hasApplicationCpe = false;
     103  216
                 vulnerability = new Vulnerability();
     104  216
                 vulnerability.setName(attributes.getValue("id"));
     105  19080
             } else if (current.isVulnProductNode()) {
     106  5816
                 nodeText = new StringBuilder(100);
     107  13264
             } else if (current.isVulnReferencesNode()) {
     108  720
                 final String lang = attributes.getValue("xml:lang");
     109  720
                 if ("en".equals(lang)) {
     110  720
                     reference = new Reference();
     111  
                 } else {
     112  0
                     reference = null;
     113  
                 }
     114  720
             } else if (reference != null && current.isVulnReferenceNode()) {
     115  720
                 reference.setUrl(attributes.getValue("href"));
     116  720
                 nodeText = new StringBuilder(130);
     117  11824
             } else if (reference != null && current.isVulnSourceNode()) {
     118  720
                 nodeText = new StringBuilder(30);
     119  11104
             } else if (current.isVulnSummaryNode()) {
     120  216
                 nodeText = new StringBuilder(500);
     121  10888
             } else if (current.isNVDNode()) {
     122  8
                 final String nvdVer = attributes.getValue("nvd_xml_version");
     123  8
                 if (!CURRENT_SCHEMA_VERSION.equals(nvdVer)) {
     124  0
                     throw new SAXNotSupportedException("Schema version " + nvdVer + " is not supported");
     125  
                 }
     126  8
             } else if (current.isVulnCWENode()) {
     127  152
                 vulnerability.setCwe(attributes.getValue("id"));
     128  10728
             } else if (current.isCVSSScoreNode()) {
     129  208
                 nodeText = new StringBuilder(5);
     130  10520
             } else if (current.isCVSSAccessVectorNode()) {
     131  208
                 nodeText = new StringBuilder(20);
     132  10312
             } else if (current.isCVSSAccessComplexityNode()) {
     133  208
                 nodeText = new StringBuilder(20);
     134  10104
             } else if (current.isCVSSAuthenticationNode()) {
     135  208
                 nodeText = new StringBuilder(20);
     136  9896
             } else if (current.isCVSSAvailabilityImpactNode()) {
     137  208
                 nodeText = new StringBuilder(20);
     138  9688
             } else if (current.isCVSSConfidentialityImpactNode()) {
     139  208
                 nodeText = new StringBuilder(20);
     140  9480
             } else if (current.isCVSSIntegrityImpactNode()) {
     141  208
                 nodeText = new StringBuilder(20);
     142  
             }
     143  19296
         }
     144  
     
     145  
         @Override
     146  
         public void characters(char[] ch, int start, int length) throws SAXException {
     147  31896
             if (nodeText != null) {
     148  9136
                 nodeText.append(ch, start, length);
     149  
             }
     150  31896
         }
     151  
     
     152  
         @Override
     153  
         public void endElement(String uri, String localName, String qName) throws SAXException {
     154  19296
             current.setNode(qName);
     155  19296
             if (current.isEntryNode()) {
     156  216
                 totalNumberOfEntries += 1;
     157  216
                 if (hasApplicationCpe) {
     158  152
                     totalNumberOfApplicationEntries += 1;
     159  
                     try {
     160  152
                         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  152
                     }
     168  
                 }
     169  216
                 vulnerability = null;
     170  19080
             } else if (current.isCVSSScoreNode()) {
     171  
                 try {
     172  208
                     final float score = Float.parseFloat(nodeText.toString());
     173  208
                     vulnerability.setCvssScore(score);
     174  0
                 } catch (NumberFormatException ex) {
     175  0
                     LOGGER.error("Error parsing CVSS Score.");
     176  0
                     LOGGER.debug("", ex);
     177  208
                 }
     178  208
                 nodeText = null;
     179  18872
             } else if (current.isCVSSAccessVectorNode()) {
     180  208
                 vulnerability.setCvssAccessVector(nodeText.toString());
     181  208
                 nodeText = null;
     182  18664
             } else if (current.isCVSSAccessComplexityNode()) {
     183  208
                 vulnerability.setCvssAccessComplexity(nodeText.toString());
     184  208
                 nodeText = null;
     185  18456
             } else if (current.isCVSSAuthenticationNode()) {
     186  208
                 vulnerability.setCvssAuthentication(nodeText.toString());
     187  208
                 nodeText = null;
     188  18248
             } else if (current.isCVSSAvailabilityImpactNode()) {
     189  208
                 vulnerability.setCvssAvailabilityImpact(nodeText.toString());
     190  208
                 nodeText = null;
     191  18040
             } else if (current.isCVSSConfidentialityImpactNode()) {
     192  208
                 vulnerability.setCvssConfidentialityImpact(nodeText.toString());
     193  208
                 nodeText = null;
     194  17832
             } else if (current.isCVSSIntegrityImpactNode()) {
     195  208
                 vulnerability.setCvssIntegrityImpact(nodeText.toString());
     196  208
                 nodeText = null;
     197  17624
             } else if (current.isVulnProductNode()) {
     198  5816
                 final String cpe = nodeText.toString();
     199  5816
                 if (cpe.startsWith("cpe:/a:")) {
     200  4912
                     hasApplicationCpe = true;
     201  4912
                     vulnerability.addVulnerableSoftware(cpe);
     202  
                 }
     203  5816
                 nodeText = null;
     204  5816
             } else if (reference != null && current.isVulnReferencesNode()) {
     205  720
                 vulnerability.addReference(reference);
     206  720
                 reference = null;
     207  11088
             } else if (reference != null && current.isVulnReferenceNode()) {
     208  720
                 reference.setName(nodeText.toString());
     209  720
                 nodeText = null;
     210  10368
             } else if (reference != null && current.isVulnSourceNode()) {
     211  720
                 reference.setSource(nodeText.toString());
     212  720
                 nodeText = null;
     213  9648
             } else if (current.isVulnSummaryNode()) {
     214  216
                 vulnerability.setDescription(nodeText.toString());
     215  216
                 if (nodeText.indexOf("** REJECT **") >= 0) {
     216  8
                     hasApplicationCpe = true; //ensure we process this to delete the vuln
     217  
                 }
     218  216
                 nodeText = null;
     219  
             }
     220  19296
         }
     221  
         /**
     222  
          * the cve database.
     223  
          */
     224  
         private CveDB cveDB;
     225  
     
     226  
         /**
     227  
          * Sets the cveDB.
     228  
          *
     229  
          * @param db a reference to the CveDB
     230  
          */
     231  
         public void setCveDB(CveDB db) {
     232  0
             cveDB = db;
     233  0
         }
     234  
         /**
     235  
          * A list of CVE entries and associated VulnerableSoftware entries that contain previous entries.
     236  
          */
     237  
         private Map<String, List<VulnerableSoftware>> prevVersionVulnMap;
     238  
     
     239  
         /**
     240  
          * Sets the prevVersionVulnMap.
     241  
          *
     242  
          * @param map the map of vulnerable software with previous versions being vulnerable
     243  
          */
     244  
         public void setPrevVersionVulnMap(Map<String, List<VulnerableSoftware>> map) {
     245  0
             prevVersionVulnMap = map;
     246  0
         }
     247  
     
     248  
         /**
     249  
          * Saves a vulnerability to the CVE Database.
     250  
          *
     251  
          * @param vuln the vulnerability to store in the database
     252  
          * @throws DatabaseException thrown if there is an error writing to the database
     253  
          * @throws CorruptIndexException is thrown if the CPE Index is corrupt
     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  152
             if (cveDB == null) {
     258  152
                 return;
     259  
             }
     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
                 }
     266  
             }
     267  0
             cveDB.updateVulnerability(vuln);
     268  0
         }
     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  8
         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  0
                 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  38592
                 this.node = node;
     357  38592
             }
     358  
     
     359  
             /**
     360  
              * Checks if the handler is at the NVD node.
     361  
              *
     362  
              * @return true or false
     363  
              */
     364  
             public boolean isNVDNode() {
     365  10888
                 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  38592
                 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  36704
                 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  15424
                 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  2880
                 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  1440
                 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  20752
                 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  10880
                 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  29808
                 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  29392
                 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  28976
                 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  28560
                 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  27728
                 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  27312
                 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  28144
                 return CVSS_AVAILABILITY_IMPACT.equals(node);
     492  
             }
     493  
         }
     494  
         // </editor-fold>
     495  
     }
    + + + + 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 new file mode 100644 index 000000000..ec7826561 --- /dev/null +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.NvdCveInfo.html @@ -0,0 +1,281 @@ + + + + +Coverage Report + + + + +
    Coverage Report - org.owasp.dependencycheck.data.update.nvd.NvdCveInfo
    +
     
    + + + + +
    Classes in this File Line Coverage Branch Coverage Complexity
    NvdCveInfo
    100%
    17/17
    N/A
    1
    +
     
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
     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.data.update.nvd;
     19  
     
     20  
     /**
     21  
      * A pojo that contains the Url and timestamp of the current NvdCve XML files.
     22  
      *
     23  
      * @author Jeremy Long
     24  
      */
     25  120
     public class NvdCveInfo {
     26  
     
     27  
         /**
     28  
          * an id.
     29  
          */
     30  
         private String id;
     31  
     
     32  
         /**
     33  
          * Get the value of id.
     34  
          *
     35  
          * @return the value of id
     36  
          */
     37  
         public String getId() {
     38  80
             return id;
     39  
         }
     40  
     
     41  
         /**
     42  
          * Set the value of id.
     43  
          *
     44  
          * @param id new value of id
     45  
          */
     46  
         public void setId(String id) {
     47  88
             this.id = id;
     48  88
         }
     49  
         /**
     50  
          * a url.
     51  
          */
     52  
         private String url;
     53  
     
     54  
         /**
     55  
          * Get the value of url.
     56  
          *
     57  
          * @return the value of url
     58  
          */
     59  
         public String getUrl() {
     60  32
             return url;
     61  
         }
     62  
     
     63  
         /**
     64  
          * Set the value of url.
     65  
          *
     66  
          * @param url new value of url
     67  
          */
     68  
         public void setUrl(String url) {
     69  88
             this.url = url;
     70  88
         }
     71  
         /**
     72  
          * The 1.2 schema URL.
     73  
          */
     74  
         private String oldSchemaVersionUrl;
     75  
     
     76  
         /**
     77  
          * Get the value of oldSchemaVersionUrl.
     78  
          *
     79  
          * @return the value of oldSchemaVersionUrl
     80  
          */
     81  
         public String getOldSchemaVersionUrl() {
     82  32
             return oldSchemaVersionUrl;
     83  
         }
     84  
     
     85  
         /**
     86  
          * Set the value of oldSchemaVersionUrl.
     87  
          *
     88  
          * @param oldSchemaVersionUrl new value of oldSchemaVersionUrl
     89  
          */
     90  
         public void setOldSchemaVersionUrl(String oldSchemaVersionUrl) {
     91  88
             this.oldSchemaVersionUrl = oldSchemaVersionUrl;
     92  88
         }
     93  
         /**
     94  
          * a timestamp - epoch time.
     95  
          */
     96  
         private long timestamp;
     97  
     
     98  
         /**
     99  
          * Get the value of timestamp - epoch time.
     100  
          *
     101  
          * @return the value of timestamp - epoch time
     102  
          */
     103  
         public long getTimestamp() {
     104  8
             return timestamp;
     105  
         }
     106  
     
     107  
         /**
     108  
          * Set the value of timestamp - epoch time.
     109  
          *
     110  
          * @param timestamp new value of timestamp - epoch time
     111  
          */
     112  
         public void setTimestamp(long timestamp) {
     113  80
             this.timestamp = timestamp;
     114  80
         }
     115  
         /**
     116  
          * indicates whether or not this item should be updated.
     117  
          */
     118  120
         private boolean needsUpdate = true;
     119  
     
     120  
         /**
     121  
          * Get the value of needsUpdate.
     122  
          *
     123  
          * @return the value of needsUpdate
     124  
          */
     125  
         public boolean getNeedsUpdate() {
     126  40
             return needsUpdate;
     127  
         }
     128  
     
     129  
         /**
     130  
          * Set the value of needsUpdate.
     131  
          *
     132  
          * @param needsUpdate new value of needsUpdate
     133  
          */
     134  
         public void setNeedsUpdate(boolean needsUpdate) {
     135  88
             this.needsUpdate = needsUpdate;
     136  88
         }
     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 new file mode 100644 index 000000000..d8a769c69 --- /dev/null +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.ProcessTask.html @@ -0,0 +1,339 @@ + + + + +Coverage Report + + + + +
    Coverage Report - org.owasp.dependencycheck.data.update.nvd.ProcessTask
    +
     
    + + + + +
    Classes in this File Line Coverage Branch Coverage Complexity
    ProcessTask
    0%
    0/51
    N/A
    3.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) 2013 Jeremy Long. All Rights Reserved.
     17  
      */
     18  
     package org.owasp.dependencycheck.data.update.nvd;
     19  
     
     20  
     import java.io.File;
     21  
     import java.io.FileNotFoundException;
     22  
     import java.io.IOException;
     23  
     import java.sql.SQLException;
     24  
     import java.util.List;
     25  
     import java.util.Map;
     26  
     import java.util.concurrent.Callable;
     27  
     import javax.xml.parsers.ParserConfigurationException;
     28  
     import javax.xml.parsers.SAXParser;
     29  
     import javax.xml.parsers.SAXParserFactory;
     30  
     import org.owasp.dependencycheck.data.nvdcve.CveDB;
     31  
     import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
     32  
     import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties;
     33  
     import org.owasp.dependencycheck.data.update.exception.UpdateException;
     34  
     import org.owasp.dependencycheck.dependency.VulnerableSoftware;
     35  
     import org.owasp.dependencycheck.utils.Settings;
     36  
     import org.slf4j.Logger;
     37  
     import org.slf4j.LoggerFactory;
     38  
     import org.xml.sax.SAXException;
     39  
     
     40  
     /**
     41  
      * A callable task that will process a given set of NVD CVE xml files and update the Cve Database accordingly.
     42  
      *
     43  
      * @author Jeremy Long
     44  
      */
     45  0
     public class ProcessTask implements Callable<ProcessTask> {
     46  
     
     47  
         /**
     48  
          * The logger.
     49  
          */
     50  0
         private static final Logger LOGGER = LoggerFactory.getLogger(ProcessTask.class);
     51  
         /**
     52  
          * A field to store any update exceptions that occur during the "call".
     53  
          */
     54  0
         private UpdateException exception = null;
     55  
     
     56  
         /**
     57  
          * Get the value of exception.
     58  
          *
     59  
          * @return the value of exception
     60  
          */
     61  
         public UpdateException getException() {
     62  0
             return exception;
     63  
         }
     64  
     
     65  
         /**
     66  
          * Set the value of exception.
     67  
          *
     68  
          * @param exception new value of exception
     69  
          */
     70  
         public void setException(UpdateException exception) {
     71  0
             this.exception = exception;
     72  0
         }
     73  
         /**
     74  
          * A reference to the CveDB.
     75  
          */
     76  
         private final CveDB cveDB;
     77  
         /**
     78  
          * A reference to the callable download task.
     79  
          */
     80  
         private final DownloadTask filePair;
     81  
         /**
     82  
          * A reference to the properties.
     83  
          */
     84  
         private final DatabaseProperties properties;
     85  
         /**
     86  
          * A reference to the global settings object.
     87  
          */
     88  
         private Settings settings;
     89  
     
     90  
         /**
     91  
          * Constructs a new ProcessTask used to process an NVD CVE update.
     92  
          *
     93  
          * @param cveDB the data store object
     94  
          * @param filePair the download task that contains the URL references to download
     95  
          * @param settings a reference to the global settings object; this is necessary so that when the thread is started the
     96  
          * dependencies have a correct reference to the global settings.
     97  
          */
     98  0
         public ProcessTask(final CveDB cveDB, final DownloadTask filePair, Settings settings) {
     99  0
             this.cveDB = cveDB;
     100  0
             this.filePair = filePair;
     101  0
             this.properties = cveDB.getDatabaseProperties();
     102  0
             this.settings = settings;
     103  0
         }
     104  
     
     105  
         /**
     106  
          * Implements the callable interface.
     107  
          *
     108  
          * @return this object
     109  
          * @throws Exception thrown if there is an exception; note that any UpdateExceptions are simply added to the tasks exception
     110  
          * collection
     111  
          */
     112  
         @Override
     113  
         public ProcessTask call() throws Exception {
     114  
             try {
     115  0
                 Settings.setInstance(settings);
     116  0
                 processFiles();
     117  0
             } catch (UpdateException ex) {
     118  0
                 this.exception = ex;
     119  
             } finally {
     120  0
                 Settings.cleanup(false);
     121  0
             }
     122  0
             return this;
     123  
         }
     124  
     
     125  
         /**
     126  
          * Imports the NVD CVE XML File into the Lucene Index.
     127  
          *
     128  
          * @param file the file containing the NVD CVE XML
     129  
          * @param oldVersion contains the file containing the NVD CVE XML 1.2
     130  
          * @throws ParserConfigurationException is thrown if there is a parser configuration exception
     131  
          * @throws SAXException is thrown if there is a SAXException
     132  
          * @throws IOException is thrown if there is a IO Exception
     133  
          * @throws SQLException is thrown if there is a SQL exception
     134  
          * @throws DatabaseException is thrown if there is a database exception
     135  
          * @throws ClassNotFoundException thrown if the h2 database driver cannot be loaded
     136  
          */
     137  
         protected void importXML(File file, File oldVersion) throws ParserConfigurationException,
     138  
                 SAXException, IOException, SQLException, DatabaseException, ClassNotFoundException {
     139  
     
     140  0
             final SAXParserFactory factory = SAXParserFactory.newInstance();
     141  0
             final SAXParser saxParser = factory.newSAXParser();
     142  
     
     143  0
             final NvdCve12Handler cve12Handler = new NvdCve12Handler();
     144  0
             saxParser.parse(oldVersion, cve12Handler);
     145  0
             final Map<String, List<VulnerableSoftware>> prevVersionVulnMap = cve12Handler.getVulnerabilities();
     146  
     
     147  0
             final NvdCve20Handler cve20Handler = new NvdCve20Handler();
     148  0
             cve20Handler.setCveDB(cveDB);
     149  0
             cve20Handler.setPrevVersionVulnMap(prevVersionVulnMap);
     150  0
             saxParser.parse(file, cve20Handler);
     151  0
         }
     152  
     
     153  
         /**
     154  
          * Processes the NVD CVE XML file and imports the data into the DB.
     155  
          *
     156  
          * @throws UpdateException thrown if there is an error loading the data into the database
     157  
          */
     158  
         private void processFiles() throws UpdateException {
     159  0
             LOGGER.info("Processing Started for NVD CVE - {}", filePair.getNvdCveInfo().getId());
     160  
             try {
     161  0
                 importXML(filePair.getFirst(), filePair.getSecond());
     162  0
                 cveDB.commit();
     163  0
                 properties.save(filePair.getNvdCveInfo());
     164  0
             } catch (FileNotFoundException ex) {
     165  0
                 throw new UpdateException(ex);
     166  0
             } catch (ParserConfigurationException ex) {
     167  0
                 throw new UpdateException(ex);
     168  0
             } catch (SAXException ex) {
     169  0
                 throw new UpdateException(ex);
     170  0
             } catch (IOException ex) {
     171  0
                 throw new UpdateException(ex);
     172  0
             } catch (SQLException ex) {
     173  0
                 throw new UpdateException(ex);
     174  0
             } catch (DatabaseException ex) {
     175  0
                 throw new UpdateException(ex);
     176  0
             } catch (ClassNotFoundException ex) {
     177  0
                 throw new UpdateException(ex);
     178  
             } finally {
     179  0
                 filePair.cleanup();
     180  0
             }
     181  0
             LOGGER.info("Processing Complete for NVD CVE - {}", filePair.getNvdCveInfo().getId());
     182  0
         }
     183  
     }
    + + + + 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 new file mode 100644 index 000000000..6787d59ed --- /dev/null +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.data.update.nvd.UpdateableNvdCve.html @@ -0,0 +1,362 @@ + + + + +Coverage Report + + + + +
    Coverage Report - org.owasp.dependencycheck.data.update.nvd.UpdateableNvdCve
    +
     
    + + + + +
    Classes in this File Line Coverage Branch Coverage Complexity
    UpdateableNvdCve
    93%
    28/30
    100%
    4/4
    1.25
    +
     
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
     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) 2012 Jeremy Long. All Rights Reserved.
     17  
      */
     18  
     package org.owasp.dependencycheck.data.update.nvd;
     19  
     
     20  
     import java.net.MalformedURLException;
     21  
     import java.net.URL;
     22  
     import java.util.Iterator;
     23  
     import java.util.Map;
     24  
     import java.util.Map.Entry;
     25  
     import java.util.TreeMap;
     26  
     import org.owasp.dependencycheck.utils.DownloadFailedException;
     27  
     import org.owasp.dependencycheck.utils.Downloader;
     28  
     
     29  
     /**
     30  
      * Contains a collection of updateable NvdCveInfo objects. This is used to determine which files need to be downloaded and
     31  
      * processed.
     32  
      *
     33  
      * @author Jeremy Long
     34  
      */
     35  96
     public class UpdateableNvdCve implements java.lang.Iterable<NvdCveInfo>, Iterator<NvdCveInfo> {
     36  
     
     37  
         /**
     38  
          * A collection of sources of data.
     39  
          */
     40  40
         private Map<String, NvdCveInfo> collection = new TreeMap<String, NvdCveInfo>();
     41  
     
     42  
         /**
     43  
          * Returns the collection of NvdCveInfo objects. This method is mainly used for testing.
     44  
          *
     45  
          * @return the collection of NvdCveInfo objects
     46  
          */
     47  
         protected Map<String, NvdCveInfo> getCollection() {
     48  24
             return collection;
     49  
         }
     50  
     
     51  
         /**
     52  
          * Gets whether or not an update is needed.
     53  
          *
     54  
          * @return true or false depending on whether an update is needed
     55  
          */
     56  
         public boolean isUpdateNeeded() {
     57  24
             for (NvdCveInfo item : this) {
     58  32
                 if (item.getNeedsUpdate()) {
     59  8
                     return true;
     60  
                 }
     61  24
             }
     62  16
             return false;
     63  
         }
     64  
     
     65  
         /**
     66  
          * Adds a new entry of updateable information to the contained collection.
     67  
          *
     68  
          * @param id the key for the item to be added
     69  
          * @param url the URL to download the item
     70  
          * @param oldUrl the URL for the old version of the item (the NVD CVE old schema still contains useful data we need).
     71  
          * @throws MalformedURLException thrown if the URL provided is invalid
     72  
          * @throws DownloadFailedException thrown if the download fails.
     73  
          */
     74  
         public void add(String id, String url, String oldUrl) throws MalformedURLException, DownloadFailedException {
     75  8
             add(id, url, oldUrl, false);
     76  8
         }
     77  
     
     78  
         /**
     79  
          * Adds a new entry of updateable information to the contained collection.
     80  
          *
     81  
          * @param id the key for the item to be added
     82  
          * @param url the URL to download the item
     83  
          * @param oldUrl the URL for the old version of the item (the NVD CVE old schema still contains useful data we need).
     84  
          * @param needsUpdate whether or not the data needs to be updated
     85  
          * @throws MalformedURLException thrown if the URL provided is invalid
     86  
          * @throws DownloadFailedException thrown if the download fails.
     87  
          */
     88  
         public void add(String id, String url, String oldUrl, boolean needsUpdate) throws MalformedURLException, DownloadFailedException {
     89  72
             final NvdCveInfo item = new NvdCveInfo();
     90  72
             item.setNeedsUpdate(needsUpdate); //the others default to true, to make life easier later this should default to false.
     91  72
             item.setId(id);
     92  72
             item.setUrl(url);
     93  72
             item.setOldSchemaVersionUrl(oldUrl);
     94  72
             item.setTimestamp(Downloader.getLastModified(new URL(url)));
     95  72
             collection.put(id, item);
     96  72
         }
     97  
     
     98  
         /**
     99  
          * Clears the contained collection of NvdCveInfo entries.
     100  
          */
     101  
         public void clear() {
     102  8
             collection.clear();
     103  8
         }
     104  
     
     105  
         /**
     106  
          * Returns the timestamp for the given entry.
     107  
          *
     108  
          * @param key the key to lookup in the collection of NvdCveInfo items
     109  
          * @return the timestamp for the given entry
     110  
          */
     111  
         public long getTimeStamp(String key) {
     112  0
             return collection.get(key).getTimestamp();
     113  
         }
     114  
         /**
     115  
          * An internal iterator used to implement iterable.
     116  
          */
     117  40
         private Iterator<Entry<String, NvdCveInfo>> iterableContent = null;
     118  
     
     119  
         /**
     120  
          * <p>
     121  
          * Returns an iterator for the NvdCveInfo contained.</p>
     122  
          * <p>
     123  
          * <b>This method is not thread safe.</b></p>
     124  
          *
     125  
          * @return an NvdCveInfo Iterator
     126  
          */
     127  
         @Override
     128  
         public Iterator<NvdCveInfo> iterator() {
     129  32
             iterableContent = collection.entrySet().iterator();
     130  32
             return this;
     131  
         }
     132  
     
     133  
         /**
     134  
          * <p>
     135  
          * Returns whether or not there is another item in the collection.</p>
     136  
          * <p>
     137  
          * <b>This method is not thread safe.</b></p>
     138  
          *
     139  
          * @return true or false depending on whether or not another item exists in the collection
     140  
          */
     141  
         @Override
     142  
         public boolean hasNext() {
     143  80
             return iterableContent.hasNext();
     144  
         }
     145  
     
     146  
         /**
     147  
          * <p>
     148  
          * Returns the next item in the collection.</p>
     149  
          * <p>
     150  
          * <b>This method is not thread safe.</b></p>
     151  
          *
     152  
          * @return the next NvdCveInfo item in the collection
     153  
          */
     154  
         @Override
     155  
         public NvdCveInfo next() {
     156  56
             return iterableContent.next().getValue();
     157  
         }
     158  
     
     159  
         /**
     160  
          * <p>
     161  
          * Removes the current NvdCveInfo object from the collection.</p>
     162  
          * <p>
     163  
          * <b>This method is not thread safe.</b></p>
     164  
          */
     165  
         @Override
     166  
         public void remove() {
     167  8
             iterableContent.remove();
     168  8
         }
     169  
     
     170  
         /**
     171  
          * Returns the specified item from the collection.
     172  
          *
     173  
          * @param key the key to lookup the return value
     174  
          * @return the NvdCveInfo object stored using the specified key
     175  
          */
     176  
         public NvdCveInfo get(String key) {
     177  16
             return collection.get(key);
     178  
         }
     179  
     
     180  
         @Override
     181  
         public String toString() {
     182  0
             return "Updateable{" + "size=" + collection.size() + '}';
     183  
         }
     184  
     }
    + + + + 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 8524159b4..117bfc479 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  9
     public enum Confidence {
    +  25  80
     public enum Confidence {
     26  
     
     27   @@ -74,32 +74,32 @@
          * High confidence evidence.
     29  
          */
    -  30  1
         HIGHEST,
    +  30  8
         HIGHEST,
     31  
         /**
     32  
          * High confidence evidence.
     33  
          */
    -  34  1
         HIGH,
    +  34  8
         HIGH,
     35  
         /**
     36  
          * Medium confidence evidence.
     37  
          */
    -  38  1
         MEDIUM,
    +  38  8
         MEDIUM,
     39  
         /**
     40  
          * Low confidence evidence.
     41  
          */
    -  42  1
         LOW
    +  42  8
         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 0491f5069..ccc7dcdd1 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
    60%
    124/205
    20%
    34/162
    2.621
    Dependency
    66%
    103/154
    26%
    18/68
    1.661
     
    @@ -76,817 +76,820 @@  29  
     import java.util.TreeSet;
     30   -
     import java.util.logging.Level;
    +
     
     31   -
     import java.util.logging.Logger;
    +
     import org.apache.commons.lang.ObjectUtils;
     32  
     import org.owasp.dependencycheck.data.nexus.MavenArtifact;
     33  
     import org.owasp.dependencycheck.utils.Checksum;
     34   -
     import org.owasp.dependencycheck.utils.FileUtils;
    +
     import org.slf4j.Logger;
     35   -
     
    +
     import org.slf4j.LoggerFactory;
     36   -
     /**
    +
     
     37   -
      * A program dependency. This object is one of the core components within DependencyCheck. It is used to collect information about
    +
     /**
     38   -
      * the dependency in the form of evidence. The Evidence is then used to determine if there are any known, published,
    +
      * A program dependency. This object is one of the core components within DependencyCheck. It is used to collect information about
     39   -
      * vulnerabilities associated with the program dependency.
    +
      * the dependency in the form of evidence. The Evidence is then used to determine if there are any known, published,
     40   -
      *
    +
      * vulnerabilities associated with the program dependency.
     41   -
      * @author Jeremy Long
    +
      *
     42   +
      * @author Jeremy Long
    +  43  
      */
    -  43  2
     public class Dependency implements Serializable, Comparable<Dependency> {
    -  44   -
     
    +  44  16
     public class Dependency implements Serializable, Comparable<Dependency> {
     45   -
         /**
    -  46   -
          * The logger.
    -  47   -
          */
    -  48  1
         private static final Logger LOGGER = Logger.getLogger(Dependency.class.getName());
    -  49   -
         /**
    -  50   -
          * The actual file path of the dependency on disk.
    -  51   -
          */
    -  52   -
         private String actualFilePath;
    -  53   -
         /**
    -  54   -
          * The file path to display.
    -  55   -
          */
    -  56   -
         private String filePath;
    -  57   -
         /**
    -  58   -
          * The file name of the dependency.
    -  59   -
          */
    -  60   -
         private String fileName;
    -  61   -
         /**
    -  62   -
          * The file extension of the dependency.
    -  63   -
          */
    -  64   -
         private String fileExtension;
    -  65   -
         /**
    -  66   -
          * The md5 hash of the dependency.
    -  67   -
          */
    -  68   -
         private String md5sum;
    -  69   -
         /**
    -  70   -
          * The SHA1 hash of the dependency.
    -  71   -
          */
    -  72   -
         private String sha1sum;
    -  73   -
         /**
    -  74   -
          * A list of Identifiers.
    -  75   -
          */
    -  76   -
         private Set<Identifier> identifiers;
    -  77   -
         /**
    -  78   -
          * A collection of vendor evidence.
    -  79   -
          */
    -  80   -
         private final EvidenceCollection vendorEvidence;
    -  81   -
         /**
    -  82   -
          * A collection of product evidence.
    -  83   -
          */
    -  84   -
         private final EvidenceCollection productEvidence;
    -  85   -
         /**
    -  86   -
          * A collection of version evidence.
    -  87   -
          */
    -  88   -
         private final EvidenceCollection versionEvidence;
    -  89  
     
    +  46   +
         /**
    +  47   +
          * The logger.
    +  48   +
          */
    +  49  8
         private static final Logger LOGGER = LoggerFactory.getLogger(Dependency.class);
    +  50   +
         /**
    +  51   +
          * Used as starting point for generating the value in {@link #hashCode()}.
    +  52   +
          */
    +  53   +
         private static final int MAGIC_HASH_INIT_VALUE = 3;
    +  54   +
         /**
    +  55   +
          * Used as a multiplier for generating the value in {@link #hashCode()}.
    +  56   +
          */
    +  57   +
         private static final int MAGIC_HASH_MULTIPLIER = 47;
    +  58   +
         /**
    +  59   +
          * The actual file path of the dependency on disk.
    +  60   +
          */
    +  61   +
         private String actualFilePath;
    +  62   +
         /**
    +  63   +
          * The file path to display.
    +  64   +
          */
    +  65   +
         private String filePath;
    +  66   +
         /**
    +  67   +
          * The file name of the dependency.
    +  68   +
          */
    +  69   +
         private String fileName;
    +  70   +
         /**
    +  71   +
          * The md5 hash of the dependency.
    +  72   +
          */
    +  73   +
         private String md5sum;
    +  74   +
         /**
    +  75   +
          * The SHA1 hash of the dependency.
    +  76   +
          */
    +  77   +
         private String sha1sum;
    +  78   +
         /**
    +  79   +
          * A list of Identifiers.
    +  80   +
          */
    +  81   +
         private Set<Identifier> identifiers;
    +  82   +
         /**
    +  83   +
          * A collection of vendor evidence.
    +  84   +
          */
    +  85   +
         private final EvidenceCollection vendorEvidence;
    +  86   +
         /**
    +  87   +
          * A collection of product evidence.
    +  88   +
          */
    +  89   +
         private final EvidenceCollection productEvidence;
     90  
         /**
     91   -
          * Constructs a new Dependency object.
    +
          * A collection of version evidence.
     92  
          */
    -  93  47
         public Dependency() {
    -  94  47
             vendorEvidence = new EvidenceCollection();
    -  95  47
             productEvidence = new EvidenceCollection();
    -  96  47
             versionEvidence = new EvidenceCollection();
    -  97  47
             identifiers = new TreeSet<Identifier>();
    -  98  47
             vulnerabilities = new TreeSet<Vulnerability>(new VulnerabilityComparator());
    -  99  47
             suppressedIdentifiers = new TreeSet<Identifier>();
    -  100  47
             suppressedVulnerabilities = new TreeSet<Vulnerability>(new VulnerabilityComparator());
    -  101  47
         }
    -  102   +  93   +
         private final EvidenceCollection versionEvidence;
    +  94  
     
    -  103   +  95  
         /**
    -  104   +  96  
          * Constructs a new Dependency object.
    -  105   -
          *
    -  106   -
          * @param file the File to create the dependency object from.
    +  97   +
          */
    +  98  432
         public Dependency() {
    +  99  432
             vendorEvidence = new EvidenceCollection();
    +  100  432
             productEvidence = new EvidenceCollection();
    +  101  432
             versionEvidence = new EvidenceCollection();
    +  102  432
             identifiers = new TreeSet<Identifier>();
    +  103  432
             vulnerabilities = new TreeSet<Vulnerability>(new VulnerabilityComparator());
    +  104  432
             suppressedIdentifiers = new TreeSet<Identifier>();
    +  105  432
             suppressedVulnerabilities = new TreeSet<Vulnerability>(new VulnerabilityComparator());
    +  106  432
         }
     107   -
          */
    +
     
     108   +
         /**
    +  109   +
          * Constructs a new Dependency object.
    +  110   +
          *
    +  111   +
          * @param file the File to create the dependency object from.
    +  112   +
          */
    +  113  
         public Dependency(File file) {
    -  109  24
             this();
    -  110  24
             this.actualFilePath = file.getPath();
    -  111  24
             this.filePath = this.actualFilePath;
    -  112  24
             this.fileName = file.getName();
    -  113  24
             this.fileExtension = FileUtils.getFileExtension(fileName);
    -  114  24
             determineHashes(file);
    -  115  24
         }
    -  116   -
     
    -  117   -
         /**
    -  118   -
          * Returns the file name of the dependency.
    -  119   -
          *
    +  114  264
             this();
    +  115  264
             this.actualFilePath = file.getAbsolutePath();
    +  116  264
             this.filePath = this.actualFilePath;
    +  117  264
             this.fileName = file.getName();
    +  118  264
             determineHashes(file);
    +  119  264
         }
     120   -
          * @return the file name of the dependency
    +
     
     121   -
          */
    +
         /**
     122   -
         public String getFileName() {
    -  123  28
             return this.fileName;
    +
          * Returns the file name of the dependency.
    +  123   +
          *
     124   -
         }
    +
          * @return the file name of the dependency
     125   -
     
    +
          */
     126   -
         /**
    -  127   -
          * Returns the file name of the dependency with the backslash escaped for use in JavaScript. This is a complete hack as I
    +
         public String getFileName() {
    +  127  288
             return this.fileName;
     128   -
          * could not get the replace to work in the template itself.
    +
         }
     129   -
          *
    +
     
     130   -
          * @return the file name of the dependency with the backslash escaped for use in JavaScript
    +
         /**
     131   -
          */
    +
          * Returns the file name of the dependency with the backslash escaped for use in JavaScript. This is a complete hack as I
     132   -
         public String getFileNameForJavaScript() {
    -  133  0
             return this.fileName.replace("\\", "\\\\");
    +
          * could not get the replace to work in the template itself.
    +  133   +
          *
     134   -
         }
    +
          * @return the file name of the dependency with the backslash escaped for use in JavaScript
     135   -
     
    +
          */
     136   -
         /**
    -  137   -
          * Sets the file name of the dependency.
    +
         public String getFileNameForJavaScript() {
    +  137  0
             return this.fileName.replace("\\", "\\\\");
     138   -
          *
    +
         }
     139   -
          * @param fileName the file name of the dependency
    +
     
     140   -
          */
    +
         /**
     141   -
         public void setFileName(String fileName) {
    -  142  7
             this.fileName = fileName;
    -  143  7
         }
    +
          * Sets the file name of the dependency.
    +  142   +
          *
    +  143   +
          * @param fileName the file name of the dependency
     144   -
     
    +
          */
     145   -
         /**
    -  146   -
          * Sets the actual file path of the dependency on disk.
    -  147   -
          *
    +
         public void setFileName(String fileName) {
    +  146  56
             this.fileName = fileName;
    +  147  56
         }
     148   -
          * @param actualFilePath the file path of the dependency
    +
     
     149   -
          */
    +
         /**
     150   +
          * Sets the actual file path of the dependency on disk.
    +  151   +
          *
    +  152   +
          * @param actualFilePath the file path of the dependency
    +  153   +
          */
    +  154  
         public void setActualFilePath(String actualFilePath) {
    -  151  2
             this.actualFilePath = actualFilePath;
    -  152  2
             if (this.sha1sum == null) {
    -  153  2
                 final File file = new File(this.actualFilePath);
    -  154  2
                 determineHashes(file);
    -  155   -
             }
    -  156  2
         }
    -  157   -
     
    -  158   -
         /**
    +  155  16
             this.actualFilePath = actualFilePath;
    +  156  16
             if (this.sha1sum == null) {
    +  157  0
                 final File file = new File(this.actualFilePath);
    +  158  0
                 determineHashes(file);
     159   -
          * Gets the file path of the dependency.
    -  160   -
          *
    -  161   -
          * @return the file path of the dependency
    -  162   -
          */
    -  163   -
         public String getActualFilePath() {
    -  164  49
             return this.actualFilePath;
    -  165   -
         }
    -  166   -
     
    -  167   -
         /**
    -  168   -
          * Gets a reference to the File object.
    -  169   -
          *
    -  170   -
          * @return the File object
    -  171   -
          */
    -  172   -
         public File getActualFile() {
    -  173  11
             return new File(this.actualFilePath);
    -  174   -
         }
    -  175   -
     
    -  176   -
         /**
    -  177   -
          * Sets the file path of the dependency.
    -  178   -
          *
    -  179   -
          * @param filePath the file path of the dependency
    -  180   -
          */
    -  181   -
         public void setFilePath(String filePath) {
    -  182  3
             this.filePath = filePath;
    -  183  3
         }
    -  184   -
     
    -  185   -
         /**
    -  186   -
          * The file name to display in reports.
    -  187   -
          */
    -  188  47
         private String displayName = null;
    -  189   -
     
    -  190   -
         /**
    -  191   -
          * Sets the file name to display in reports.
    -  192   -
          *
    -  193   -
          * @param displayName the name to display
    -  194   -
          */
    -  195   -
         public void setDisplayFileName(String displayName) {
    -  196  4
             this.displayName = displayName;
    -  197  4
         }
    -  198   -
     
    -  199   -
         /**
    -  200   -
          * Returns the file name to display in reports; if no display file name has been set it will default to the actual file name.
    -  201   -
          *
    -  202   -
          * @return the file name to display
    -  203   -
          */
    -  204   -
         public String getDisplayFileName() {
    -  205  1
             if (displayName == null) {
    -  206  0
                 return this.fileName;
    -  207  
             }
    -  208  1
             return this.displayName;
    -  209   -
         }
    -  210   +  160  16
         }
    +  161  
     
    -  211   +  162  
         /**
    -  212   -
          * <p>
    -  213   -
          * Gets the file path of the dependency.</p>
    -  214   -
          * <p>
    -  215   -
          * <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
    -  216   -
          * the getActualFilePath().</p>
    -  217   +  163   +
          * Gets the file path of the dependency.
    +  164  
          *
    -  218   +  165  
          * @return the file path of the dependency
    +  166   +
          */
    +  167   +
         public String getActualFilePath() {
    +  168  392
             return this.actualFilePath;
    +  169   +
         }
    +  170   +
     
    +  171   +
         /**
    +  172   +
          * Gets a reference to the File object.
    +  173   +
          *
    +  174   +
          * @return the File object
    +  175   +
          */
    +  176   +
         public File getActualFile() {
    +  177  416
             return new File(this.actualFilePath);
    +  178   +
         }
    +  179   +
     
    +  180   +
         /**
    +  181   +
          * Sets the file path of the dependency.
    +  182   +
          *
    +  183   +
          * @param filePath the file path of the dependency
    +  184   +
          */
    +  185   +
         public void setFilePath(String filePath) {
    +  186  56
             this.filePath = filePath;
    +  187  56
         }
    +  188   +
     
    +  189   +
         /**
    +  190   +
          * The file name to display in reports.
    +  191   +
          */
    +  192  432
         private String displayName = null;
    +  193   +
     
    +  194   +
         /**
    +  195   +
          * Sets the file name to display in reports.
    +  196   +
          *
    +  197   +
          * @param displayName the name to display
    +  198   +
          */
    +  199   +
         public void setDisplayFileName(String displayName) {
    +  200  128
             this.displayName = displayName;
    +  201  128
         }
    +  202   +
     
    +  203   +
         /**
    +  204   +
          * Returns the file name to display in reports; if no display file name has been set it will default to the actual file name.
    +  205   +
          *
    +  206   +
          * @return the file name to display
    +  207   +
          */
    +  208   +
         public String getDisplayFileName() {
    +  209  80
             if (displayName == null) {
    +  210  0
                 return this.fileName;
    +  211   +
             }
    +  212  80
             return this.displayName;
    +  213   +
         }
    +  214   +
     
    +  215   +
         /**
    +  216   +
          * <p>
    +  217   +
          * Gets the file path of the dependency.</p>
    +  218   +
          * <p>
     219   -
          */
    +
          * <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
     220   -
         public String getFilePath() {
    -  221  24
             return this.filePath;
    +
          * the getActualFilePath().</p>
    +  221   +
          *
     222   -
         }
    +
          * @return the file path of the dependency
     223   -
     
    +
          */
     224   -
         /**
    -  225   -
          * Sets the file extension of the dependency.
    +
         public String getFilePath() {
    +  225  224
             return this.filePath;
     226   -
          *
    +
         }
     227   -
          * @param fileExtension the file name of the dependency
    +
     
     228   -
          */
    +
         /**
     229   -
         public void setFileExtension(String fileExtension) {
    -  230  2
             this.fileExtension = fileExtension;
    -  231  2
         }
    -  232   -
     
    -  233   -
         /**
    -  234   -
          * Gets the file extension of the dependency.
    -  235   -
          *
    -  236   -
          * @return the file extension of the dependency
    -  237   -
          */
    -  238   -
         public String getFileExtension() {
    -  239  35
             return this.fileExtension;
    -  240   -
         }
    -  241   -
     
    -  242   -
         /**
    -  243  
          * Returns the MD5 Checksum of the dependency file.
    -  244   +  230  
          *
    -  245   +  231  
          * @return the MD5 Checksum
    -  246   +  232  
          */
    -  247   +  233  
         public String getMd5sum() {
    -  248  2
             return this.md5sum;
    -  249   +  234  16
             return this.md5sum;
    +  235  
         }
    -  250   +  236  
     
    -  251   +  237  
         /**
    -  252   +  238  
          * Sets the MD5 Checksum of the dependency.
    -  253   +  239  
          *
    -  254   +  240  
          * @param md5sum the MD5 Checksum
    -  255   +  241  
          */
    -  256   +  242  
         public void setMd5sum(String md5sum) {
    -  257  27
             this.md5sum = md5sum;
    -  258  27
         }
    -  259   +  243  272
             this.md5sum = md5sum;
    +  244  272
         }
    +  245  
     
    -  260   +  246  
         /**
    -  261   +  247  
          * Returns the SHA1 Checksum of the dependency.
    -  262   +  248  
          *
    -  263   +  249  
          * @return the SHA1 Checksum
    -  264   +  250  
          */
    -  265   +  251  
         public String getSha1sum() {
    -  266  9
             return this.sha1sum;
    -  267   +  252  72
             return this.sha1sum;
    +  253  
         }
    -  268   +  254  
     
    -  269   +  255  
         /**
    -  270   +  256  
          * Sets the SHA1 Checksum of the dependency.
    -  271   +  257  
          *
    -  272   +  258  
          * @param sha1sum the SHA1 Checksum
    -  273   +  259  
          */
    -  274   +  260  
         public void setSha1sum(String sha1sum) {
    -  275  29
             this.sha1sum = sha1sum;
    -  276  29
         }
    -  277   +  261  336
             this.sha1sum = sha1sum;
    +  262  336
         }
    +  263  
     
    -  278   +  264  
         /**
    -  279   +  265  
          * Returns a List of Identifiers.
    -  280   +  266  
          *
    -  281   +  267  
          * @return an ArrayList of Identifiers
    -  282   +  268  
          */
    -  283   +  269  
         public Set<Identifier> getIdentifiers() {
    -  284  102
             return this.identifiers;
    -  285   +  270  880
             return this.identifiers;
    +  271  
         }
    -  286   +  272  
     
    -  287   +  273  
         /**
    -  288   +  274  
          * Sets a List of Identifiers.
    -  289   +  275  
          *
    -  290   +  276  
          * @param identifiers A list of Identifiers
    -  291   +  277  
          */
    -  292   +  278  
         public void setIdentifiers(Set<Identifier> identifiers) {
    -  293  1
             this.identifiers = identifiers;
    -  294  1
         }
    -  295   +  279  8
             this.identifiers = identifiers;
    +  280  8
         }
    +  281  
     
    -  296   +  282  
         /**
    -  297   +  283  
          * Adds an entry to the list of detected Identifiers for the dependency file.
    -  298   +  284  
          *
    -  299   +  285  
          * @param type the type of identifier (such as CPE)
    -  300   +  286  
          * @param value the value of the identifier
    -  301   +  287  
          * @param url the URL of the identifier
    -  302   +  288  
          */
    -  303   +  289  
         public void addIdentifier(String type, String value, String url) {
    -  304  11
             final Identifier i = new Identifier(type, value, url);
    -  305  11
             this.identifiers.add(i);
    -  306  11
         }
    +  290  88
             final Identifier i = new Identifier(type, value, url);
    +  291  88
             this.identifiers.add(i);
    +  292  88
         }
    +  293   +
     
    +  294   +
         /**
    +  295   +
          * Adds an entry to the list of detected Identifiers for the dependency file.
    +  296   +
          *
    +  297   +
          * @param type the type of identifier (such as CPE)
    +  298   +
          * @param value the value of the identifier
    +  299   +
          * @param url the URL of the identifier
    +  300   +
          * @param confidence the confidence in the Identifier being accurate
    +  301   +
          */
    +  302   +
         public void addIdentifier(String type, String value, String url, Confidence confidence) {
    +  303  16
             final Identifier i = new Identifier(type, value, url);
    +  304  16
             i.setConfidence(confidence);
    +  305  16
             this.identifiers.add(i);
    +  306  16
         }
     307  
     
     308  
         /**
     309   -
          * Adds an entry to the list of detected Identifiers for the dependency file.
    +
          * Adds the maven artifact as evidence.
     310  
          *
     311   -
          * @param type the type of identifier (such as CPE)
    -  312   -
          * @param value the value of the identifier
    -  313   -
          * @param url the URL of the identifier
    -  314   -
          * @param confidence the confidence in the Identifier being accurate
    -  315   -
          */
    -  316   -
         public void addIdentifier(String type, String value, String url, Confidence confidence) {
    -  317  2
             final Identifier i = new Identifier(type, value, url);
    -  318  2
             i.setConfidence(confidence);
    -  319  2
             this.identifiers.add(i);
    -  320  2
         }
    -  321   -
     
    -  322   -
         /**
    -  323   -
          * Adds the maven artifact as evidence.
    -  324   -
          *
    -  325  
          * @param source The source of the evidence
    -  326   +  312  
          * @param mavenArtifact The maven artifact
    -  327   +  313  
          * @param confidence The confidence level of this evidence
    -  328   +  314  
          */
    -  329   +  315  
         public void addAsEvidence(String source, MavenArtifact mavenArtifact, Confidence confidence) {
    -  330  2
             if (mavenArtifact.getGroupId() != null && !mavenArtifact.getGroupId().isEmpty()) {
    -  331  1
                 this.getVendorEvidence().addEvidence(source, "groupid", mavenArtifact.getGroupId(), confidence);
    -  332   +  316  16
             if (mavenArtifact.getGroupId() != null && !mavenArtifact.getGroupId().isEmpty()) {
    +  317  8
                 this.getVendorEvidence().addEvidence(source, "groupid", mavenArtifact.getGroupId(), confidence);
    +  318  
             }
    -  333  2
             if (mavenArtifact.getArtifactId() != null && !mavenArtifact.getArtifactId().isEmpty()) {
    -  334  1
                 this.getProductEvidence().addEvidence(source, "artifactid", mavenArtifact.getArtifactId(), confidence);
    -  335   +  319  16
             if (mavenArtifact.getArtifactId() != null && !mavenArtifact.getArtifactId().isEmpty()) {
    +  320  8
                 this.getProductEvidence().addEvidence(source, "artifactid", mavenArtifact.getArtifactId(), confidence);
    +  321  
             }
    -  336  2
             if (mavenArtifact.getVersion() != null && !mavenArtifact.getVersion().isEmpty()) {
    -  337  1
                 this.getVersionEvidence().addEvidence(source, "version", mavenArtifact.getVersion(), confidence);
    -  338   +  322  16
             if (mavenArtifact.getVersion() != null && !mavenArtifact.getVersion().isEmpty()) {
    +  323  8
                 this.getVersionEvidence().addEvidence(source, "version", mavenArtifact.getVersion(), confidence);
    +  324  
             }
    -  339  2
             if (mavenArtifact.getArtifactUrl() != null && !mavenArtifact.getArtifactUrl().isEmpty()) {
    -  340  1
                 boolean found = false;
    -  341  1
                 for (Identifier i : this.getIdentifiers()) {
    -  342  0
                     if ("maven".equals(i.getType()) && i.getValue().equals(mavenArtifact.toString())) {
    -  343  0
                         found = true;
    -  344  0
                         i.setConfidence(Confidence.HIGHEST);
    -  345  0
                         final String url = "http://search.maven.org/#search|ga|1|1%3A%22" + this.getSha1sum() + "%22";
    -  346  0
                         i.setUrl(url);
    -  347   +  325  16
             if (mavenArtifact.getArtifactUrl() != null && !mavenArtifact.getArtifactUrl().isEmpty()) {
    +  326  8
                 boolean found = false;
    +  327  8
                 for (Identifier i : this.getIdentifiers()) {
    +  328  0
                     if ("maven".equals(i.getType()) && i.getValue().equals(mavenArtifact.toString())) {
    +  329  0
                         found = true;
    +  330  0
                         i.setConfidence(Confidence.HIGHEST);
    +  331  0
                         final String url = "http://search.maven.org/#search|ga|1|1%3A%22" + this.getSha1sum() + "%22";
    +  332  0
                         i.setUrl(url);
    +  333  
                         //i.setUrl(mavenArtifact.getArtifactUrl());
    -  348  0
                         LOGGER.fine(String.format("Already found identifier %s. Confidence set to highest", i.getValue()));
    -  349  0
                         break;
    -  350   +  334  0
                         LOGGER.debug("Already found identifier {}. Confidence set to highest", i.getValue());
    +  335  0
                         break;
    +  336  
                     }
    -  351  0
                 }
    -  352  1
                 if (!found) {
    -  353  1
                     LOGGER.fine(String.format("Adding new maven identifier %s", mavenArtifact.toString()));
    -  354  1
                     this.addIdentifier("maven", mavenArtifact.toString(), mavenArtifact.getArtifactUrl(), Confidence.HIGHEST);
    -  355   +  337  0
                 }
    +  338  8
                 if (!found) {
    +  339  8
                     LOGGER.debug("Adding new maven identifier {}", mavenArtifact.toString());
    +  340  8
                     this.addIdentifier("maven", mavenArtifact.toString(), mavenArtifact.getArtifactUrl(), Confidence.HIGHEST);
    +  341  
                 }
    -  356   +  342  
             }
    -  357  2
         }
    +  343  16
         }
    +  344   +
     
    +  345   +
         /**
    +  346   +
          * Adds an entry to the list of detected Identifiers for the dependency file.
    +  347   +
          *
    +  348   +
          * @param identifier the identifier to add
    +  349   +
          */
    +  350   +
         public void addIdentifier(Identifier identifier) {
    +  351  24
             this.identifiers.add(identifier);
    +  352  24
         }
    +  353   +
     
    +  354   +
         /**
    +  355   +
          * A set of identifiers that have been suppressed.
    +  356   +
          */
    +  357   +
         private Set<Identifier> suppressedIdentifiers;
     358  
     
     359  
         /**
     360   -
          * Adds an entry to the list of detected Identifiers for the dependency file.
    +
          * Get the value of suppressedIdentifiers.
     361  
          *
     362   -
          * @param identifier the identifier to add
    +
          * @return the value of suppressedIdentifiers
     363  
          */
     364   -
         public void addIdentifier(Identifier identifier) {
    -  365  2
             this.identifiers.add(identifier);
    -  366  2
         }
    +
         public Set<Identifier> getSuppressedIdentifiers() {
    +  365  40
             return suppressedIdentifiers;
    +  366   +
         }
     367  
     
     368  
         /**
     369   -
          * A set of identifiers that have been suppressed.
    -  370   -
          */
    -  371   -
         private Set<Identifier> suppressedIdentifiers;
    -  372   -
     
    -  373   -
         /**
    -  374   -
          * Get the value of suppressedIdentifiers.
    -  375   -
          *
    -  376   -
          * @return the value of suppressedIdentifiers
    -  377   -
          */
    -  378   -
         public Set<Identifier> getSuppressedIdentifiers() {
    -  379  5
             return suppressedIdentifiers;
    -  380   -
         }
    -  381   -
     
    -  382   -
         /**
    -  383  
          * Set the value of suppressedIdentifiers.
    -  384   +  370  
          *
    -  385   +  371  
          * @param suppressedIdentifiers new value of suppressedIdentifiers
    -  386   +  372  
          */
    -  387   +  373  
         public void setSuppressedIdentifiers(Set<Identifier> suppressedIdentifiers) {
    -  388  0
             this.suppressedIdentifiers = suppressedIdentifiers;
    -  389  0
         }
    +  374  0
             this.suppressedIdentifiers = suppressedIdentifiers;
    +  375  0
         }
    +  376   +
     
    +  377   +
         /**
    +  378   +
          * Adds an identifier to the list of suppressed identifiers.
    +  379   +
          *
    +  380   +
          * @param identifier an identifier that was suppressed.
    +  381   +
          */
    +  382   +
         public void addSuppressedIdentifier(Identifier identifier) {
    +  383  32
             this.suppressedIdentifiers.add(identifier);
    +  384  32
         }
    +  385   +
     
    +  386   +
         /**
    +  387   +
          * A set of vulnerabilities that have been suppressed.
    +  388   +
          */
    +  389   +
         private SortedSet<Vulnerability> suppressedVulnerabilities;
     390  
     
     391  
         /**
     392   -
          * Adds an identifier to the list of suppressed identifiers.
    +
          * Get the value of suppressedVulnerabilities.
     393  
          *
     394   -
          * @param identifier an identifier that was suppressed.
    +
          * @return the value of suppressedVulnerabilities
     395  
          */
     396   -
         public void addSuppressedIdentifier(Identifier identifier) {
    -  397  4
             this.suppressedIdentifiers.add(identifier);
    -  398  4
         }
    +
         public SortedSet<Vulnerability> getSuppressedVulnerabilities() {
    +  397  24
             return suppressedVulnerabilities;
    +  398   +
         }
     399  
     
     400  
         /**
     401   -
          * A set of vulnerabilities that have been suppressed.
    -  402   -
          */
    -  403   -
         private SortedSet<Vulnerability> suppressedVulnerabilities;
    -  404   -
     
    -  405   -
         /**
    -  406   -
          * Get the value of suppressedVulnerabilities.
    -  407   -
          *
    -  408   -
          * @return the value of suppressedVulnerabilities
    -  409   -
          */
    -  410   -
         public SortedSet<Vulnerability> getSuppressedVulnerabilities() {
    -  411  3
             return suppressedVulnerabilities;
    -  412   -
         }
    -  413   -
     
    -  414   -
         /**
    -  415  
          * Set the value of suppressedVulnerabilities.
    -  416   +  402  
          *
    -  417   +  403  
          * @param suppressedVulnerabilities new value of suppressedVulnerabilities
    -  418   +  404  
          */
    -  419   +  405  
         public void setSuppressedVulnerabilities(SortedSet<Vulnerability> suppressedVulnerabilities) {
    -  420  0
             this.suppressedVulnerabilities = suppressedVulnerabilities;
    -  421  0
         }
    -  422   +  406  0
             this.suppressedVulnerabilities = suppressedVulnerabilities;
    +  407  0
         }
    +  408  
     
    -  423   +  409  
         /**
    -  424   +  410  
          * Adds a vulnerability to the set of suppressed vulnerabilities.
    -  425   +  411  
          *
    -  426   +  412  
          * @param vulnerability the vulnerability that was suppressed
    -  427   +  413  
          */
    -  428   +  414  
         public void addSuppressedVulnerability(Vulnerability vulnerability) {
    -  429  3
             this.suppressedVulnerabilities.add(vulnerability);
    -  430  3
         }
    -  431   +  415  24
             this.suppressedVulnerabilities.add(vulnerability);
    +  416  24
         }
    +  417  
     
    -  432   +  418  
         /**
    -  433   +  419  
          * Returns the evidence used to identify this dependency.
    -  434   +  420  
          *
    -  435   +  421  
          * @return an EvidenceCollection.
    -  436   +  422  
          */
    -  437   +  423  
         public EvidenceCollection getEvidence() {
    -  438  11
             return EvidenceCollection.merge(this.productEvidence, this.vendorEvidence, this.versionEvidence);
    -  439   +  424  88
             return EvidenceCollection.merge(this.productEvidence, this.vendorEvidence, this.versionEvidence);
    +  425  
         }
    -  440   +  426  
     
    -  441   +  427  
         /**
    -  442   +  428  
          * Returns the evidence used to identify this dependency.
    -  443   +  429  
          *
    -  444   +  430  
          * @return an EvidenceCollection.
    -  445   +  431  
          */
    -  446   +  432  
         public Set<Evidence> getEvidenceForDisplay() {
    -  447  0
             return EvidenceCollection.mergeForDisplay(this.productEvidence, this.vendorEvidence, this.versionEvidence);
    -  448   +  433  0
             return EvidenceCollection.mergeForDisplay(this.productEvidence, this.vendorEvidence, this.versionEvidence);
    +  434  
         }
    -  449   +  435  
     
    -  450   +  436  
         /**
    -  451   +  437  
          * Returns the evidence used to identify this dependency.
    -  452   +  438  
          *
    -  453   +  439  
          * @return an EvidenceCollection.
    -  454   +  440  
          */
    -  455   +  441  
         public EvidenceCollection getEvidenceUsed() {
    -  456  1
             return EvidenceCollection.mergeUsed(this.productEvidence, this.vendorEvidence, this.versionEvidence);
    -  457   +  442  8
             return EvidenceCollection.mergeUsed(this.productEvidence, this.vendorEvidence, this.versionEvidence);
    +  443  
         }
    -  458   +  444  
     
    -  459   +  445  
         /**
    -  460   +  446  
          * Gets the Vendor Evidence.
    -  461   +  447  
          *
    -  462   +  448  
          * @return an EvidenceCollection.
    -  463   +  449  
          */
    -  464   +  450  
         public EvidenceCollection getVendorEvidence() {
    -  465  86
             return this.vendorEvidence;
    -  466   +  451  800
             return this.vendorEvidence;
    +  452  
         }
    -  467   +  453  
     
    -  468   +  454  
         /**
    -  469   +  455  
          * Gets the Product Evidence.
    -  470   +  456  
          *
    -  471   +  457  
          * @return an EvidenceCollection.
    -  472   +  458  
          */
    -  473   +  459  
         public EvidenceCollection getProductEvidence() {
    -  474  121
             return this.productEvidence;
    -  475   +  460  1128
             return this.productEvidence;
    +  461  
         }
    +  462   +
     
    +  463   +
         /**
    +  464   +
          * Gets the Version Evidence.
    +  465   +
          *
    +  466   +
          * @return an EvidenceCollection.
    +  467   +
          */
    +  468   +
         public EvidenceCollection getVersionEvidence() {
    +  469  536
             return this.versionEvidence;
    +  470   +
         }
    +  471   +
     
    +  472   +
         /**
    +  473   +
          * The description of the JAR file.
    +  474   +
          */
    +  475   +
         private String description;
     476  
     
     477  
         /**
     478   -
          * Gets the Version Evidence.
    +
          * Get the value of description.
     479  
          *
     480   -
          * @return an EvidenceCollection.
    +
          * @return the value of description
     481  
          */
     482   -
         public EvidenceCollection getVersionEvidence() {
    -  483  46
             return this.versionEvidence;
    +
         public String getDescription() {
    +  483  72
             return description;
     484  
         }
     485   @@ -894,558 +897,482 @@  486  
         /**
     487   -
          * The description of the JAR file.
    +
          * Set the value of description.
     488   -
          */
    -  489   -
         private String description;
    -  490   -
     
    -  491   -
         /**
    -  492   -
          * Get the value of description.
    -  493  
          *
    -  494   -
          * @return the value of description
    -  495   +  489   +
          * @param description new value of description
    +  490  
          */
    +  491   +
         public void setDescription(String description) {
    +  492  144
             this.description = description;
    +  493  144
         }
    +  494   +
     
    +  495   +
         /**
     496   -
         public String getDescription() {
    -  497  9
             return description;
    +
          * The license that this dependency uses.
    +  497   +
          */
     498   -
         }
    +
         private String license;
     499  
     
     500  
         /**
     501   -
          * Set the value of description.
    +
          * Get the value of license.
     502  
          *
     503   -
          * @param description new value of description
    +
          * @return the value of license
     504  
          */
     505   -
         public void setDescription(String description) {
    -  506  18
             this.description = description;
    -  507  18
         }
    +
         public String getLicense() {
    +  506  16
             return license;
    +  507   +
         }
     508  
     
     509  
         /**
     510   -
          * The license that this dependency uses.
    +
          * Set the value of license.
     511   -
          */
    -  512   -
         private String license;
    -  513   -
     
    -  514   -
         /**
    -  515   -
          * Get the value of license.
    -  516  
          *
    -  517   -
          * @return the value of license
    -  518   +  512   +
          * @param license new value of license
    +  513  
          */
    +  514   +
         public void setLicense(String license) {
    +  515  16
             this.license = license;
    +  516  16
         }
    +  517   +
     
    +  518   +
         /**
     519   -
         public String getLicense() {
    -  520  2
             return license;
    +
          * A list of vulnerabilities for this dependency.
    +  520   +
          */
     521   -
         }
    +
         private SortedSet<Vulnerability> vulnerabilities;
     522  
     
     523  
         /**
     524   -
          * Set the value of license.
    +
          * Get the list of vulnerabilities.
     525  
          *
     526   -
          * @param license new value of license
    +
          * @return the list of vulnerabilities
     527  
          */
     528   -
         public void setLicense(String license) {
    -  529  2
             this.license = license;
    -  530  2
         }
    +
         public SortedSet<Vulnerability> getVulnerabilities() {
    +  529  112
             return vulnerabilities;
    +  530   +
         }
     531  
     
     532  
         /**
     533   -
          * A list of vulnerabilities for this dependency.
    -  534   -
          */
    -  535   -
         private SortedSet<Vulnerability> vulnerabilities;
    -  536   -
     
    -  537   -
         /**
    -  538   -
          * Get the list of vulnerabilities.
    -  539   -
          *
    -  540   -
          * @return the list of vulnerabilities
    -  541   -
          */
    -  542   -
         public SortedSet<Vulnerability> getVulnerabilities() {
    -  543  13
             return vulnerabilities;
    -  544   -
         }
    -  545   -
     
    -  546   -
         /**
    -  547  
          * Set the value of vulnerabilities.
    -  548   +  534  
          *
    -  549   +  535  
          * @param vulnerabilities new value of vulnerabilities
    -  550   +  536  
          */
    -  551   +  537  
         public void setVulnerabilities(SortedSet<Vulnerability> vulnerabilities) {
    -  552  0
             this.vulnerabilities = vulnerabilities;
    -  553  0
         }
    -  554   +  538  0
             this.vulnerabilities = vulnerabilities;
    +  539  0
         }
    +  540  
     
    -  555   +  541  
         /**
    -  556   +  542  
          * Determines the sha1 and md5 sum for the given file.
    -  557   +  543  
          *
    -  558   +  544  
          * @param file the file to create checksums for
    -  559   +  545  
          */
    -  560   +  546  
         private void determineHashes(File file) {
    -  561  26
             String md5 = null;
    -  562  26
             String sha1 = null;
    -  563   +  547  264
             String md5 = null;
    +  548  264
             String sha1 = null;
    +  549  
             try {
    -  564  26
                 md5 = Checksum.getMD5Checksum(file);
    -  565  23
                 sha1 = Checksum.getSHA1Checksum(file);
    -  566  3
             } catch (IOException ex) {
    -  567  3
                 final String msg = String.format("Unable to read '%s' to determine hashes.", file.getName());
    -  568  3
                 LOGGER.log(Level.WARNING, msg);
    -  569  3
                 LOGGER.log(Level.FINE, null, ex);
    -  570  0
             } catch (NoSuchAlgorithmException ex) {
    -  571  0
                 final String msg = "Unable to use MD5 of SHA1 checksums.";
    -  572  0
                 LOGGER.log(Level.WARNING, msg);
    -  573  0
                 LOGGER.log(Level.FINE, null, ex);
    -  574  26
             }
    -  575  26
             this.setMd5sum(md5);
    -  576  26
             this.setSha1sum(sha1);
    -  577  26
         }
    -  578   +  550  264
                 md5 = Checksum.getMD5Checksum(file);
    +  551  256
                 sha1 = Checksum.getSHA1Checksum(file);
    +  552  8
             } catch (IOException ex) {
    +  553  8
                 LOGGER.warn("Unable to read '{}' to determine hashes.", file.getName());
    +  554  8
                 LOGGER.debug("", ex);
    +  555  0
             } catch (NoSuchAlgorithmException ex) {
    +  556  0
                 LOGGER.warn("Unable to use MD5 of SHA1 checksums.");
    +  557  0
                 LOGGER.debug("", ex);
    +  558  264
             }
    +  559  264
             this.setMd5sum(md5);
    +  560  264
             this.setSha1sum(sha1);
    +  561  264
         }
    +  562  
     
    -  579   +  563  
         /**
    -  580   +  564  
          * Adds a vulnerability to the dependency.
    -  581   +  565  
          *
    -  582   +  566  
          * @param vulnerability a vulnerability outlining a vulnerability.
    -  583   +  567  
          */
    -  584   +  568  
         public void addVulnerability(Vulnerability vulnerability) {
    -  585  3
             this.vulnerabilities.add(vulnerability);
    -  586  3
         }
    -  587   +  569  24
             this.vulnerabilities.add(vulnerability);
    +  570  24
         }
    +  571  
     
    -  588   +  572  
         /**
    -  589   +  573  
          * A collection of related dependencies.
    -  590   +  574  
          */
    -  591  47
         private Set<Dependency> relatedDependencies = new TreeSet<Dependency>();
    -  592   +  575  432
         private Set<Dependency> relatedDependencies = new TreeSet<Dependency>();
    +  576  
     
    -  593   +  577  
         /**
    -  594   -
          * Get the value of relatedDependencies.
    -  595   +  578   +
          * Get the value of {@link #relatedDependencies}. This field is used to collect other dependencies which really represent the
    +  579   +
          * same dependency, and may be presented as one item in reports.
    +  580  
          *
    -  596   +  581  
          * @return the value of relatedDependencies
    -  597   +  582  
          */
    -  598   +  583  
         public Set<Dependency> getRelatedDependencies() {
    -  599  0
             return relatedDependencies;
    -  600   +  584  0
             return relatedDependencies;
    +  585  
         }
    -  601   +  586  
     
    -  602   +  587  
         /**
    -  603   +  588  
          * A list of projects that reference this dependency.
    -  604   +  589  
          */
    -  605  47
         private Set<String> projectReferences = new HashSet<String>();
    -  606   +  590  432
         private Set<String> projectReferences = new HashSet<String>();
    +  591  
     
    -  607   +  592  
         /**
    -  608   +  593  
          * Get the value of projectReferences.
    -  609   +  594  
          *
    -  610   +  595  
          * @return the value of projectReferences
    -  611   +  596  
          */
    -  612   +  597  
         public Set<String> getProjectReferences() {
    -  613  0
             return projectReferences;
    -  614   +  598  0
             return projectReferences;
    +  599  
         }
    -  615   +  600  
     
    -  616   +  601  
         /**
    -  617   +  602  
          * Set the value of projectReferences.
    -  618   +  603  
          *
    -  619   +  604  
          * @param projectReferences new value of projectReferences
    -  620   +  605  
          */
    -  621   +  606  
         public void setProjectReferences(Set<String> projectReferences) {
    -  622  0
             this.projectReferences = projectReferences;
    -  623  0
         }
    -  624   +  607  0
             this.projectReferences = projectReferences;
    +  608  0
         }
    +  609  
     
    -  625   +  610  
         /**
    -  626   +  611  
          * Adds a project reference.
    -  627   +  612  
          *
    -  628   +  613  
          * @param projectReference a project reference
    -  629   +  614  
          */
    -  630   +  615  
         public void addProjectReference(String projectReference) {
    -  631  0
             this.projectReferences.add(projectReference);
    -  632  0
         }
    -  633   +  616  0
             this.projectReferences.add(projectReference);
    +  617  0
         }
    +  618  
     
    -  634   +  619  
         /**
    -  635   +  620  
          * Add a collection of project reference.
    -  636   +  621  
          *
    -  637   +  622  
          * @param projectReferences a set of project references
    -  638   +  623  
          */
    -  639   +  624  
         public void addAllProjectReferences(Set<String> projectReferences) {
    -  640  0
             this.projectReferences.addAll(projectReferences);
    -  641  0
         }
    -  642   +  625  0
             this.projectReferences.addAll(projectReferences);
    +  626  0
         }
    +  627  
     
    -  643   +  628  
         /**
    -  644   +  629  
          * Set the value of relatedDependencies.
    -  645   +  630  
          *
    -  646   +  631  
          * @param relatedDependencies new value of relatedDependencies
    -  647   +  632  
          */
    -  648   +  633  
         public void setRelatedDependencies(Set<Dependency> relatedDependencies) {
    -  649  0
             this.relatedDependencies = relatedDependencies;
    -  650  0
         }
    -  651   +  634  0
             this.relatedDependencies = relatedDependencies;
    +  635  0
         }
    +  636  
     
    -  652   +  637  
         /**
    -  653   -
          * Adds a related dependency.
    -  654   +  638   +
          * Adds a related dependency. The internal collection is normally a {@link java.util.TreeSet}, which relies on
    +  639   +
          * {@link #compareTo(Dependency)}. A consequence of this is that if you attempt to add a dependency with the same file path
    +  640   +
          * (modulo character case) as one that is already in the collection, it won't get added.
    +  641  
          *
    -  655   +  642  
          * @param dependency a reference to the related dependency
    -  656   +  643  
          */
    -  657   +  644  
         public void addRelatedDependency(Dependency dependency) {
    -  658  0
             if (this == dependency) {
    -  659  0
                 LOGGER.warning("Attempted to add a circular reference - please post the log file to issue #172 here "
    -  660   -
                         + "https://github.com/jeremylong/DependencyCheck/issues/172 ");
    -  661  0
                 LOGGER.log(Level.FINE, "this: {0}", this.toString());
    -  662  0
                 LOGGER.log(Level.FINE, "dependency: {0}", dependency.toString());
    -  663   -
             } else {
    -  664  0
                 relatedDependencies.add(dependency);
    -  665   +  645  0
             if (this == dependency) {
    +  646  0
                 LOGGER.warn("Attempted to add a circular reference - please post the log file to issue #172 here "
    +  647   +
                         + "https://github.com/jeremylong/DependencyCheck/issues/172");
    +  648  0
                 LOGGER.debug("this: {}", this);
    +  649  0
                 LOGGER.debug("dependency: {}", dependency);
    +  650  0
             } else if (!relatedDependencies.add(dependency)) {
    +  651  0
                 LOGGER.debug("Failed to add dependency, likely due to referencing the same file as another dependency in the set.");
    +  652  0
                 LOGGER.debug("this: {}", this);
    +  653  0
                 LOGGER.debug("dependency: {}", dependency);
    +  654  
             }
    -  666  0
         }
    -  667   +  655  0
         }
    +  656  
     
    -  668   +  657  
         /**
    -  669   +  658  
          * A list of available versions.
    -  670   +  659  
          */
    -  671  47
         private List<String> availableVersions = new ArrayList<String>();
    -  672   +  660  432
         private List<String> availableVersions = new ArrayList<String>();
    +  661  
     
    -  673   +  662  
         /**
    -  674   +  663  
          * Get the value of availableVersions.
    -  675   +  664  
          *
    -  676   +  665  
          * @return the value of availableVersions
    -  677   +  666  
          */
    -  678   +  667  
         public List<String> getAvailableVersions() {
    -  679  0
             return availableVersions;
    -  680   +  668  0
             return availableVersions;
    +  669  
         }
    -  681   +  670  
     
    -  682   +  671  
         /**
    -  683   +  672  
          * Set the value of availableVersions.
    -  684   +  673  
          *
    -  685   +  674  
          * @param availableVersions new value of availableVersions
    -  686   +  675  
          */
    -  687   +  676  
         public void setAvailableVersions(List<String> availableVersions) {
    -  688  0
             this.availableVersions = availableVersions;
    -  689  0
         }
    -  690   +  677  0
             this.availableVersions = availableVersions;
    +  678  0
         }
    +  679  
     
    -  691   +  680  
         /**
    -  692   +  681  
          * Adds a version to the available version list.
    -  693   +  682  
          *
    -  694   +  683  
          * @param version the version to add to the list
    -  695   +  684  
          */
    -  696   +  685  
         public void addAvailableVersion(String version) {
    -  697  0
             this.availableVersions.add(version);
    -  698  0
         }
    -  699   +  686  0
             this.availableVersions.add(version);
    +  687  0
         }
    +  688  
     
    -  700   +  689  
         /**
    -  701   -
          * Implementation of the Comparable<Dependency> interface. The comparison is solely based on the file name.
    -  702   +  690   +
          * Implementation of the Comparable<Dependency> interface. The comparison is solely based on the file path.
    +  691  
          *
    -  703   +  692  
          * @param o a dependency to compare
    -  704   +  693  
          * @return an integer representing the natural ordering
    -  705   +  694  
          */
    -  706   +  695  
         public int compareTo(Dependency o) {
    -  707  2
             return this.getFilePath().compareToIgnoreCase(o.getFilePath());
    -  708   +  696  16
             return this.getFilePath().compareToIgnoreCase(o.getFilePath());
    +  697  
         }
    -  709   +  698  
     
    -  710   +  699  
         /**
    -  711   +  700  
          * Implementation of the equals method.
    -  712   +  701  
          *
    -  713   +  702  
          * @param obj the object to compare
    -  714   +  703  
          * @return true if the objects are equal, otherwise false
    -  715   +  704  
          */
    -  716   +  705  
         @Override
    -  717   +  706  
         public boolean equals(Object obj) {
    -  718  0
             if (obj == null) {
    -  719  0
                 return false;
    +  707  0
             if (obj == null || getClass() != obj.getClass()) {
    +  708  0
                 return false;
    +  709   +
             }
    +  710  0
             final Dependency other = (Dependency) obj;
    +  711  0
             return ObjectUtils.equals(this.actualFilePath, other.actualFilePath)
    +  712   +
                     && ObjectUtils.equals(this.filePath, other.filePath)
    +  713   +
                     && ObjectUtils.equals(this.fileName, other.fileName)
    +  714   +
                     && ObjectUtils.equals(this.md5sum, other.md5sum)
    +  715   +
                     && ObjectUtils.equals(this.sha1sum, other.sha1sum)
    +  716   +
                     && ObjectUtils.equals(this.identifiers, other.identifiers)
    +  717   +
                     && ObjectUtils.equals(this.vendorEvidence, other.vendorEvidence)
    +  718   +
                     && ObjectUtils.equals(this.productEvidence, other.productEvidence)
    +  719   +
                     && ObjectUtils.equals(this.versionEvidence, other.versionEvidence)
     720   -
             }
    -  721  0
             if (getClass() != obj.getClass()) {
    -  722  0
                 return false;
    +
                     && ObjectUtils.equals(this.description, other.description)
    +  721   +
                     && ObjectUtils.equals(this.license, other.license)
    +  722   +
                     && ObjectUtils.equals(this.vulnerabilities, other.vulnerabilities)
     723   -
             }
    -  724  0
             final Dependency other = (Dependency) obj;
    -  725  0
             if ((this.actualFilePath == null) ? (other.actualFilePath != null) : !this.actualFilePath.equals(other.actualFilePath)) {
    -  726  0
                 return false;
    +
                     && ObjectUtils.equals(this.relatedDependencies, other.relatedDependencies)
    +  724   +
                     && ObjectUtils.equals(this.projectReferences, other.projectReferences)
    +  725   +
                     && ObjectUtils.equals(this.availableVersions, other.availableVersions);
    +  726   +
         }
     727   -
             }
    -  728  0
             if ((this.filePath == null) ? (other.filePath != null) : !this.filePath.equals(other.filePath)) {
    -  729  0
                 return false;
    -  730   -
             }
    -  731  0
             if ((this.fileName == null) ? (other.fileName != null) : !this.fileName.equals(other.fileName)) {
    -  732  0
                 return false;
    -  733   -
             }
    -  734  0
             if ((this.fileExtension == null) ? (other.fileExtension != null) : !this.fileExtension.equals(other.fileExtension)) {
    -  735  0
                 return false;
    -  736   -
             }
    -  737  0
             if ((this.md5sum == null) ? (other.md5sum != null) : !this.md5sum.equals(other.md5sum)) {
    -  738  0
                 return false;
    -  739   -
             }
    -  740  0
             if ((this.sha1sum == null) ? (other.sha1sum != null) : !this.sha1sum.equals(other.sha1sum)) {
    -  741  0
                 return false;
    -  742   -
             }
    -  743  0
             if (this.identifiers != other.identifiers && (this.identifiers == null || !this.identifiers.equals(other.identifiers))) {
    -  744  0
                 return false;
    -  745   -
             }
    -  746  0
             if (this.vendorEvidence != other.vendorEvidence && (this.vendorEvidence == null || !this.vendorEvidence.equals(other.vendorEvidence))) {
    -  747  0
                 return false;
    -  748   -
             }
    -  749  0
             if (this.productEvidence != other.productEvidence && (this.productEvidence == null || !this.productEvidence.equals(other.productEvidence))) {
    -  750  0
                 return false;
    -  751   -
             }
    -  752  0
             if (this.versionEvidence != other.versionEvidence && (this.versionEvidence == null || !this.versionEvidence.equals(other.versionEvidence))) {
    -  753  0
                 return false;
    -  754   -
             }
    -  755  0
             if ((this.description == null) ? (other.description != null) : !this.description.equals(other.description)) {
    -  756  0
                 return false;
    -  757   -
             }
    -  758  0
             if ((this.license == null) ? (other.license != null) : !this.license.equals(other.license)) {
    -  759  0
                 return false;
    -  760   -
             }
    -  761  0
             if (this.vulnerabilities != other.vulnerabilities && (this.vulnerabilities == null || !this.vulnerabilities.equals(other.vulnerabilities))) {
    -  762  0
                 return false;
    -  763   -
             }
    -  764  0
             if (this.relatedDependencies != other.relatedDependencies
    -  765   -
                     && (this.relatedDependencies == null || !this.relatedDependencies.equals(other.relatedDependencies))) {
    -  766  0
                 return false;
    -  767   -
             }
    -  768  0
             if (this.projectReferences != other.projectReferences
    -  769   -
                     && (this.projectReferences == null || !this.projectReferences.equals(other.projectReferences))) {
    -  770  0
                 return false;
    -  771   -
             }
    -  772  0
             if (this.availableVersions != other.availableVersions
    -  773   -
                     && (this.availableVersions == null || !this.availableVersions.equals(other.availableVersions))) {
    -  774  0
                 return false;
    -  775   -
             }
    -  776  
     
    -  777  0
             return true;
    -  778   -
         }
    -  779   -
     
    -  780   +  728  
         /**
    -  781   +  729  
          * Generates the HashCode.
    -  782   +  730  
          *
    -  783   +  731  
          * @return the HashCode
    -  784   +  732  
          */
    -  785   +  733  
         @Override
    -  786   +  734  
         public int hashCode() {
    -  787  32
             int hash = 3;
    -  788  32
             hash = 47 * hash + (this.actualFilePath != null ? this.actualFilePath.hashCode() : 0);
    -  789  32
             hash = 47 * hash + (this.filePath != null ? this.filePath.hashCode() : 0);
    -  790  32
             hash = 47 * hash + (this.fileName != null ? this.fileName.hashCode() : 0);
    -  791  32
             hash = 47 * hash + (this.fileExtension != null ? this.fileExtension.hashCode() : 0);
    -  792  32
             hash = 47 * hash + (this.md5sum != null ? this.md5sum.hashCode() : 0);
    -  793  32
             hash = 47 * hash + (this.sha1sum != null ? this.sha1sum.hashCode() : 0);
    -  794  32
             hash = 47 * hash + (this.identifiers != null ? this.identifiers.hashCode() : 0);
    -  795  32
             hash = 47 * hash + (this.vendorEvidence != null ? this.vendorEvidence.hashCode() : 0);
    -  796  32
             hash = 47 * hash + (this.productEvidence != null ? this.productEvidence.hashCode() : 0);
    -  797  32
             hash = 47 * hash + (this.versionEvidence != null ? this.versionEvidence.hashCode() : 0);
    -  798  32
             hash = 47 * hash + (this.description != null ? this.description.hashCode() : 0);
    -  799  32
             hash = 47 * hash + (this.license != null ? this.license.hashCode() : 0);
    -  800  32
             hash = 47 * hash + (this.vulnerabilities != null ? this.vulnerabilities.hashCode() : 0);
    -  801  32
             hash = 47 * hash + (this.relatedDependencies != null ? this.relatedDependencies.hashCode() : 0);
    -  802  32
             hash = 47 * hash + (this.projectReferences != null ? this.projectReferences.hashCode() : 0);
    -  803  32
             hash = 47 * hash + (this.availableVersions != null ? this.availableVersions.hashCode() : 0);
    -  804  32
             return hash;
    -  805   +  735  304
             int hash = MAGIC_HASH_INIT_VALUE;
    +  736  4864
             for (Object field : new Object[]{this.actualFilePath, this.filePath, this.fileName, this.md5sum,
    +  737   +
                 this.sha1sum, this.identifiers, this.vendorEvidence, this.productEvidence, this.versionEvidence,
    +  738   +
                 this.description, this.license, this.vulnerabilities, this.relatedDependencies, this.projectReferences,
    +  739   +
                 this.availableVersions}) {
    +  740  4560
                 hash = MAGIC_HASH_MULTIPLIER * hash + ObjectUtils.hashCode(field);
    +  741   +
             }
    +  742  304
             return hash;
    +  743  
         }
    -  806   +  744  
     
    -  807   +  745  
         /**
    -  808   +  746  
          * Standard toString() implementation showing the filename, actualFilePath, and filePath.
    -  809   +  747  
          *
    -  810   +  748  
          * @return the string representation of the file
    -  811   +  749  
          */
    -  812   +  750  
         @Override
    -  813   +  751  
         public String toString() {
    -  814  0
             return "Dependency{ fileName='" + fileName + "', actualFilePath='" + actualFilePath + "', filePath='" + filePath + "'}";
    -  815   +  752  0
             return "Dependency{ fileName='" + fileName + "', actualFilePath='" + actualFilePath + "', filePath='" + filePath + "'}";
    +  753  
         }
    -  816   +  754  
     }
    - + 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 c5668868a..b5e0091f7 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Evidence.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Evidence.html @@ -12,7 +12,7 @@
     
    - +
    Classes in this File Line Coverage Branch Coverage Complexity
    Evidence
    65%
    50/76
    48%
    36/74
    3.273
    Evidence
    67%
    39/58
    61%
    21/34
    2.389
     
    @@ -56,545 +56,479 @@  19  
     
     20   -
     import java.io.Serializable;
    +
     import org.apache.commons.lang.ObjectUtils;
     21   -
     
    +
     import org.apache.commons.lang.StringUtils;
     22   -
     /**
    +
     
     23   -
      * Evidence is a piece of information about a Dependency.
    +
     import java.io.Serializable;
     24   -
      *
    +
     
     25   -
      * @author Jeremy Long
    +
     /**
     26   -
      */
    -  27  41156
     public class Evidence implements Serializable, Comparable<Evidence> {
    +
      * Evidence is a piece of information about a Dependency.
    +  27   +
      *
     28   -
     
    +
      * @author Jeremy Long
     29   -
         /**
    -  30   -
          * Creates a new Evidence object.
    +
      */
    +  30  306480
     public class Evidence implements Serializable, Comparable<Evidence> {
     31   -
          */
    -  32  0
         public Evidence() {
    -  33  0
         }
    +
     
    +  32   +
         /**
    +  33   +
          * Used as starting point for generating the value in {@link #hashCode()}.
     34   -
     
    +
          */
     35   -
         /**
    +
         private static final int MAGIC_HASH_INIT_VALUE = 3;
     36   -
          * Creates a new Evidence objects.
    -  37   -
          *
    -  38   -
          * @param source the source of the evidence.
    -  39   -
          * @param name the name of the evidence.
    -  40   -
          * @param value the value of the evidence.
    -  41   -
          * @param confidence the confidence of the evidence.
    -  42   -
          */
    -  43  15577
         public Evidence(String source, String name, String value, Confidence confidence) {
    -  44  15577
             this.source = source;
    -  45  15577
             this.name = name;
    -  46  15577
             this.value = value;
    -  47  15577
             this.confidence = confidence;
    -  48  15577
         }
    -  49   -
         /**
    -  50   -
          * The name of the evidence.
    -  51   -
          */
    -  52   -
         private String name;
    -  53  
     
    -  54   +  37  
         /**
    -  55   -
          * Get the value of name.
    -  56   -
          *
    -  57   -
          * @return the value of name
    -  58   +  38   +
          * Used as a multiplier for generating the value in {@link #hashCode()}.
    +  39  
          */
    -  59   -
         public String getName() {
    -  60  24
             return name;
    -  61   -
         }
    +  40   +
         private static final int MAGIC_HASH_MULTIPLIER = 67;
    +  41   +
     
    +  42   +
         /**
    +  43   +
          * Creates a new Evidence object.
    +  44   +
          */
    +  45  0
         public Evidence() {
    +  46  0
         }
    +  47   +
     
    +  48   +
         /**
    +  49   +
          * Creates a new Evidence objects.
    +  50   +
          *
    +  51   +
          * @param source     the source of the evidence.
    +  52   +
          * @param name       the name of the evidence.
    +  53   +
          * @param value      the value of the evidence.
    +  54   +
          * @param confidence the confidence of the evidence.
    +  55   +
          */
    +  56  117192
         public Evidence(String source, String name, String value, Confidence confidence) {
    +  57  117192
             this.source = source;
    +  58  117192
             this.name = name;
    +  59  117192
             this.value = value;
    +  60  117192
             this.confidence = confidence;
    +  61  117192
         }
     62  
     
     63  
         /**
     64   -
          * Set the value of name.
    +
          * The name of the evidence.
     65   -
          *
    +
          */
     66   -
          * @param name new value of name
    +
         private String name;
     67   -
          */
    +
     
     68   -
         public void setName(String name) {
    -  69  0
             this.name = name;
    -  70  0
         }
    +
         /**
    +  69   +
          * Get the value of name.
    +  70   +
          *
     71   -
         /**
    +
          * @return the value of name
     72   -
          * The source of the evidence.
    +
          */
     73   -
          */
    -  74   -
         private String source;
    +
         public String getName() {
    +  74  192
             return name;
     75   -
     
    -  76   -
         /**
    -  77   -
          * Get the value of source.
    -  78   -
          *
    -  79   -
          * @return the value of source
    -  80   -
          */
    -  81   -
         public String getSource() {
    -  82  11
             return source;
    -  83  
         }
    -  84   +  76  
     
    -  85   +  77  
         /**
    -  86   -
          * Set the value of source.
    -  87   +  78   +
          * Set the value of name.
    +  79  
          *
    -  88   -
          * @param source new value of source
    -  89   +  80   +
          * @param name new value of name
    +  81  
          */
    -  90   -
         public void setSource(String source) {
    -  91  0
             this.source = source;
    -  92  0
         }
    -  93   +  82   +
         public void setName(String name) {
    +  83  0
             this.name = name;
    +  84  0
         }
    +  85   +
     
    +  86  
         /**
    +  87   +
          * The source of the evidence.
    +  88   +
          */
    +  89   +
         private String source;
    +  90   +
     
    +  91   +
         /**
    +  92   +
          * Get the value of source.
    +  93   +
          *
     94   -
          * The value of the evidence.
    +
          * @return the value of source
     95  
          */
     96   -
         private String value;
    -  97   -
     
    +
         public String getSource() {
    +  97  88
             return source;
     98   -
         /**
    +
         }
     99   -
          * Get the value of value.
    +
     
     100   -
          *
    +
         /**
     101   -
          * @return the value of value
    +
          * Set the value of source.
     102   -
          */
    +
          *
     103   -
         public String getValue() {
    -  104  866
             used = true;
    -  105  866
             return value;
    -  106   -
         }
    -  107   -
     
    +
          * @param source new value of source
    +  104   +
          */
    +  105   +
         public void setSource(String source) {
    +  106  0
             this.source = source;
    +  107  0
         }
     108   -
         /**
    -  109   -
          * Get the value of value. If setUsed is set to false this call to get will not mark the evidence as used.
    -  110   -
          *
    -  111   -
          * @param setUsed whether or not this call to getValue should cause the used flag to be updated
    -  112   -
          * @return the value of value
    -  113   -
          */
    -  114   -
         public String getValue(Boolean setUsed) {
    -  115  52
             used = used || setUsed;
    -  116  52
             return value;
    -  117   -
         }
    -  118  
     
    -  119   +  109  
         /**
    -  120   -
          * Set the value of value.
    -  121   -
          *
    -  122   -
          * @param value new value of value
    -  123   +  110   +
          * The value of the evidence.
    +  111  
          */
    -  124   -
         public void setValue(String value) {
    -  125  0
             this.value = value;
    -  126  0
         }
    -  127   +  112   +
         private String value;
    +  113   +
     
    +  114  
         /**
    +  115   +
          * Get the value of value.
    +  116   +
          *
    +  117   +
          * @return the value of value
    +  118   +
          */
    +  119   +
         public String getValue() {
    +  120  6200
             used = true;
    +  121  6200
             return value;
    +  122   +
         }
    +  123   +
     
    +  124   +
         /**
    +  125   +
          * Get the value of value. If setUsed is set to false this call to get will not mark the evidence as used.
    +  126   +
          *
    +  127   +
          * @param setUsed whether or not this call to getValue should cause the used flag to be updated
     128   -
          * A value indicating if the Evidence has been "used" (aka read).
    +
          * @return the value of value
     129  
          */
     130   -
         private boolean used;
    -  131   -
     
    -  132   -
         /**
    +
         public String getValue(Boolean setUsed) {
    +  131  400
             used = used || setUsed;
    +  132  400
             return value;
     133   -
          * Get the value of used.
    -  134   -
          *
    -  135   -
          * @return the value of used
    -  136   -
          */
    -  137   -
         public boolean isUsed() {
    -  138  1279
             return used;
    -  139  
         }
    -  140   +  134  
     
    -  141   +  135  
         /**
    -  142   -
          * Set the value of used.
    -  143   +  136   +
          * Set the value of value.
    +  137  
          *
    -  144   -
          * @param used new value of used
    -  145   +  138   +
          * @param value new value of value
    +  139  
          */
    +  140   +
         public void setValue(String value) {
    +  141  0
             this.value = value;
    +  142  0
         }
    +  143   +
     
    +  144   +
         /**
    +  145   +
          * A value indicating if the Evidence has been "used" (aka read).
     146   -
         public void setUsed(boolean used) {
    -  147  0
             this.used = used;
    -  148  0
         }
    +
          */
    +  147   +
         private boolean used;
    +  148   +
     
     149  
         /**
     150   -
          * The confidence level for the evidence.
    +
          * Get the value of used.
     151   -
          */
    +
          *
     152   -
         private Confidence confidence;
    +
          * @return the value of used
     153   -
     
    +
          */
     154   -
         /**
    -  155   -
          * Get the value of confidence.
    +
         public boolean isUsed() {
    +  155  8656
             return used;
     156   -
          *
    -  157   -
          * @return the value of confidence
    -  158   -
          */
    -  159   -
         public Confidence getConfidence() {
    -  160  239
             return confidence;
    -  161  
         }
    -  162   +  157  
     
    -  163   +  158  
         /**
    -  164   -
          * Set the value of confidence.
    -  165   +  159   +
          * Set the value of used.
    +  160  
          *
    -  166   -
          * @param confidence new value of confidence
    -  167   +  161   +
          * @param used new value of used
    +  162  
          */
    +  163   +
         public void setUsed(boolean used) {
    +  164  0
             this.used = used;
    +  165  0
         }
    +  166   +
     
    +  167   +
         /**
     168   -
         public void setConfidence(Confidence confidence) {
    -  169  0
             this.confidence = confidence;
    -  170  0
         }
    +
          * The confidence level for the evidence.
    +  169   +
          */
    +  170   +
         private Confidence confidence;
     171  
     
     172  
         /**
     173   -
          * Implements the hashCode for Evidence.
    +
          * Get the value of confidence.
     174  
          *
     175   -
          * @return hash code.
    +
          * @return the value of confidence
     176  
          */
     177   -
         @Override
    -  178   -
         public int hashCode() {
    -  179  5
             int hash = 3;
    -  180  5
             hash = 67 * hash + (this.name != null ? this.name.hashCode() : 0);
    -  181  5
             hash = 67 * hash + (this.source != null ? this.source.hashCode() : 0);
    -  182  5
             hash = 67 * hash + (this.value != null ? this.value.hashCode() : 0);
    -  183  5
             hash = 67 * hash + (this.confidence != null ? this.confidence.hashCode() : 0);
    -  184  5
             return hash;
    +
         public Confidence getConfidence() {
    +  178  1904
             return confidence;
    +  179   +
         }
    +  180   +
     
    +  181   +
         /**
    +  182   +
          * Set the value of confidence.
    +  183   +
          *
    +  184   +
          * @param confidence new value of confidence
     185   -
         }
    +
          */
     186   -
     
    -  187   -
         /**
    -  188   -
          * Implements equals for Evidence.
    +
         public void setConfidence(Confidence confidence) {
    +  187  0
             this.confidence = confidence;
    +  188  0
         }
     189   -
          *
    +
     
     190   -
          * @param that an object to check the equality of.
    +
         /**
     191   -
          * @return whether the two objects are equal.
    +
          * Implements the hashCode for Evidence.
     192   -
          */
    +
          *
     193   -
         @Override
    +
          * @return hash code.
     194   -
         public boolean equals(Object that) {
    -  195  9
             if (this == that) {
    -  196  0
                 return true;
    -  197   -
             }
    -  198  9
             if (!(that instanceof Evidence)) {
    -  199  0
                 return false;
    -  200   -
             }
    -  201  9
             final Evidence e = (Evidence) that;
    -  202   -
     
    -  203  9
             return testEquality(name, e.name) && testEquality(source, e.source) && testEquality(value, e.value)
    -  204   -
                     && (confidence == null ? e.confidence == null : confidence == e.confidence);
    -  205   -
         }
    -  206   -
     
    -  207   -
         /**
    -  208   -
          * Simple equality test for use within the equals method. This does a case insensitive compare.
    -  209   -
          *
    -  210   -
          * @param l a string to compare.
    -  211   -
          * @param r another string to compare.
    -  212   -
          * @return whether the two strings are the same.
    -  213  
          */
    -  214   -
         private boolean testEquality(String l, String r) {
    -  215  11
             return l == null ? r == null : l.equalsIgnoreCase(r);
    -  216   -
         }
    -  217   -
     
    -  218   -
         /**
    -  219   -
          * Implementation of the comparable interface.
    -  220   -
          *
    -  221   -
          * @param o the evidence being compared
    -  222   -
          * @return an integer indicating the ordering of the two objects
    -  223   -
          */
    -  224   -
         public int compareTo(Evidence o) {
    -  225  41166
             if (o == null) {
    -  226  0
                 return 1;
    -  227   -
             }
    -  228  41166
             if (equalsWithNullCheck(source, o.source)) {
    -  229  24548
                 if (equalsWithNullCheck(name, o.name)) {
    -  230  24395
                     if (equalsWithNullCheck(value, o.value)) {
    -  231  15470
                         if (equalsWithNullCheck(confidence, o.confidence)) {
    -  232  15457
                             return 0; //they are equal
    -  233   -
                         } else {
    -  234  13
                             return compareToWithNullCheck(confidence, o.confidence);
    -  235   -
                         }
    -  236   -
                     } else {
    -  237  8925
                         return compareToIgnoreCaseWithNullCheck(value, o.value);
    -  238   -
                     }
    -  239   -
                 } else {
    -  240  153
                     return compareToIgnoreCaseWithNullCheck(name, o.name);
    -  241   -
                 }
    -  242   -
             } else {
    -  243  16618
                 return compareToIgnoreCaseWithNullCheck(source, o.source);
    -  244   -
             }
    -  245   -
         }
    -  246   -
     
    -  247   -
         /**
    -  248   -
          * Equality check with an exhaustive, possibly duplicative, check against nulls.
    -  249   -
          *
    -  250   -
          * @param me the value to be compared
    -  251   -
          * @param other the other value to be compared
    -  252   -
          * @return true if the values are equal; otherwise false
    -  253   -
          */
    -  254   -
         private boolean equalsWithNullCheck(String me, String other) {
    -  255  90109
             if (me == null && other == null) {
    -  256  0
                 return true;
    -  257  90109
             } else if (me == null || other == null) {
    -  258  0
                 return false;
    -  259   -
             }
    -  260  90109
             return me.equalsIgnoreCase(other);
    -  261   -
         }
    -  262   -
     
    -  263   -
         /**
    -  264   -
          * Equality check with an exhaustive, possibly duplicative, check against nulls.
    -  265   -
          *
    -  266   -
          * @param me the value to be compared
    -  267   -
          * @param other the other value to be compared
    -  268   -
          * @return true if the values are equal; otherwise false
    -  269   -
          */
    -  270   -
         private boolean equalsWithNullCheck(Confidence me, Confidence other) {
    -  271  15470
             if (me == null && other == null) {
    -  272  0
                 return true;
    -  273  15470
             } else if (me == null || other == null) {
    -  274  0
                 return false;
    -  275   -
             }
    -  276  15470
             return me.equals(other);
    -  277   -
         }
    -  278   -
     
    -  279   -
         /**
    -  280   -
          * Wrapper around {@link java.lang.String#compareToIgnoreCase(java.lang.String) String.compareToIgnoreCase} with an
    -  281   -
          * exhaustive, possibly duplicative, check against nulls.
    -  282   -
          *
    -  283   -
          * @param me the value to be compared
    -  284   -
          * @param other the other value to be compared
    -  285   -
          * @return true if the values are equal; otherwise false
    -  286   -
          */
    -  287   -
         private int compareToIgnoreCaseWithNullCheck(String me, String other) {
    -  288  25696
             if (me == null && other == null) {
    -  289  0
                 return 0;
    -  290  25696
             } else if (me == null) {
    -  291  0
                 return -1; //the other string is greater then me
    -  292  25696
             } else if (other == null) {
    -  293  0
                 return 1; //me is greater then the other string
    -  294   -
             }
    -  295  25696
             return me.compareToIgnoreCase(other);
    -  296   -
         }
    -  297   -
     
    -  298   -
         /**
    -  299   -
          * Wrapper around {@link java.lang.Enum#compareTo(java.lang.Enum) Enum.compareTo} with an exhaustive, possibly duplicative,
    -  300   -
          * check against nulls.
    -  301   -
          *
    -  302   -
          * @param me the value to be compared
    -  303   -
          * @param other the other value to be compared
    -  304   -
          * @return true if the values are equal; otherwise false
    -  305   -
          */
    -  306   -
         private int compareToWithNullCheck(Confidence me, Confidence other) {
    -  307  13
             if (me == null && other == null) {
    -  308  0
                 return 0;
    -  309  13
             } else if (me == null) {
    -  310  0
                 return -1; //the other string is greater then me
    -  311  13
             } else if (other == null) {
    -  312  0
                 return 1; //me is greater then the other string
    -  313   -
             }
    -  314  13
             return me.compareTo(other);
    -  315   -
         }
    -  316   -
     
    -  317   -
         /**
    -  318   -
          * Standard toString() implementation.
    -  319   -
          *
    -  320   -
          * @return the string representation of the object
    -  321   -
          */
    -  322   +  195  
         @Override
    -  323   -
         public String toString() {
    -  324  0
             return "Evidence{" + "name=" + name + ", source=" + source + ", value=" + value + ", confidence=" + confidence + '}';
    -  325   +  196   +
         public int hashCode() {
    +  197  56
             int hash = MAGIC_HASH_INIT_VALUE;
    +  198  56
             hash = MAGIC_HASH_MULTIPLIER * hash + ObjectUtils.hashCode(StringUtils.lowerCase(this.name));
    +  199  56
             hash = MAGIC_HASH_MULTIPLIER * hash + ObjectUtils.hashCode(StringUtils.lowerCase(this.source));
    +  200  56
             hash = MAGIC_HASH_MULTIPLIER * hash + ObjectUtils.hashCode(StringUtils.lowerCase(this.value));
    +  201  56
             hash = MAGIC_HASH_MULTIPLIER * hash + ObjectUtils.hashCode(this.confidence);
    +  202  56
             return hash;
    +  203  
         }
    -  326   +  204   +
     
    +  205   +
         /**
    +  206   +
          * Implements equals for Evidence.
    +  207   +
          *
    +  208   +
          * @param that an object to check the equality of.
    +  209   +
          * @return whether the two objects are equal.
    +  210   +
          */
    +  211   +
         @Override
    +  212   +
         public boolean equals(Object that) {
    +  213  80
             if (this == that) {
    +  214  0
                 return true;
    +  215   +
             }
    +  216  80
             if (!(that instanceof Evidence)) {
    +  217  0
                 return false;
    +  218   +
             }
    +  219  80
             final Evidence e = (Evidence) that;
    +  220   +
     
    +  221  80
             return StringUtils.equalsIgnoreCase(name, e.name)
    +  222   +
                     && StringUtils.equalsIgnoreCase(source, e.source)
    +  223   +
                     && StringUtils.equalsIgnoreCase(value, e.value)
    +  224   +
                     && ObjectUtils.equals(confidence, e.confidence);
    +  225   +
         }
    +  226   +
     
    +  227   +
         /**
    +  228   +
          * Implementation of the comparable interface.
    +  229   +
          *
    +  230   +
          * @param o the evidence being compared
    +  231   +
          * @return an integer indicating the ordering of the two objects
    +  232   +
          */
    +  233   +
         public int compareTo(Evidence o) {
    +  234  306560
             if (o == null) {
    +  235  0
                 return 1;
    +  236   +
             }
    +  237  306560
             if (StringUtils.equalsIgnoreCase(source, o.source)) {
    +  238  188912
                 if (StringUtils.equalsIgnoreCase(name, o.name)) {
    +  239  187768
                     if (StringUtils.equalsIgnoreCase(value, o.value)) {
    +  240  116296
                         if (ObjectUtils.equals(confidence, o.confidence)) {
    +  241  116184
                             return 0; //they are equal
    +  242   +
                         } else {
    +  243  112
                             return ObjectUtils.compare(confidence, o.confidence);
    +  244   +
                         }
    +  245   +
                     } else {
    +  246  71472
                         return compareToIgnoreCaseWithNullCheck(value, o.value);
    +  247   +
                     }
    +  248   +
                 } else {
    +  249  1144
                     return compareToIgnoreCaseWithNullCheck(name, o.name);
    +  250   +
                 }
    +  251   +
             } else {
    +  252  117648
                 return compareToIgnoreCaseWithNullCheck(source, o.source);
    +  253   +
             }
    +  254   +
         }
    +  255   +
     
    +  256   +
         /**
    +  257   +
          * Wrapper around {@link java.lang.String#compareToIgnoreCase(java.lang.String) String.compareToIgnoreCase} with an
    +  258   +
          * exhaustive, possibly duplicative, check against nulls.
    +  259   +
          *
    +  260   +
          * @param me    the value to be compared
    +  261   +
          * @param other the other value to be compared
    +  262   +
          * @return true if the values are equal; otherwise false
    +  263   +
          */
    +  264   +
         private int compareToIgnoreCaseWithNullCheck(String me, String other) {
    +  265  190264
             if (me == null && other == null) {
    +  266  0
                 return 0;
    +  267  190264
             } else if (me == null) {
    +  268  0
                 return -1; //the other string is greater then me
    +  269  190264
             } else if (other == null) {
    +  270  0
                 return 1; //me is greater then the other string
    +  271   +
             }
    +  272  190264
             return me.compareToIgnoreCase(other);
    +  273   +
         }
    +  274   +
     
    +  275   +
         /**
    +  276   +
          * Standard toString() implementation.
    +  277   +
          *
    +  278   +
          * @return the string representation of the object
    +  279   +
          */
    +  280   +
         @Override
    +  281   +
         public String toString() {
    +  282  0
             return "Evidence{" + "name=" + name + ", source=" + source + ", value=" + value + ", confidence=" + confidence + '}';
    +  283   +
         }
    +  284  
     }
    - + 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 517e22ca6..888ef61ba 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.EvidenceCollection.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.EvidenceCollection.html @@ -12,12 +12,12 @@
     
    - - - - - - + + + + + +
    Classes in this File Line Coverage Branch Coverage Complexity
    EvidenceCollection
    70%
    75/106
    59%
    38/64
    2.833
    EvidenceCollection$1
    100%
    2/2
    100%
    2/2
    2.833
    EvidenceCollection$2
    100%
    2/2
    100%
    2/2
    2.833
    EvidenceCollection$3
    100%
    2/2
    100%
    2/2
    2.833
    EvidenceCollection$4
    100%
    2/2
    100%
    2/2
    2.833
    EvidenceCollection$5
    100%
    2/2
    N/A
    2.833
    EvidenceCollection
    71%
    75/105
    61%
    38/62
    2.792
    EvidenceCollection$1
    100%
    2/2
    100%
    2/2
    2.792
    EvidenceCollection$2
    100%
    2/2
    100%
    2/2
    2.792
    EvidenceCollection$3
    100%
    2/2
    100%
    2/2
    2.792
    EvidenceCollection$4
    100%
    2/2
    100%
    2/2
    2.792
    EvidenceCollection$5
    100%
    2/2
    N/A
    2.792
     
    @@ -75,19 +75,19 @@  26  
     import java.util.TreeSet;
     27   -
     import java.util.logging.Level;
    -  28   -
     import java.util.logging.Logger;
    -  29  
     import org.apache.commons.lang.StringUtils;
    -  30   +  28  
     import org.owasp.dependencycheck.utils.DependencyVersion;
    -  31   +  29  
     import org.owasp.dependencycheck.utils.DependencyVersionUtil;
    -  32   +  30  
     import org.owasp.dependencycheck.utils.Filter;
    -  33   +  31  
     import org.owasp.dependencycheck.utils.UrlStringUtils;
    +  32   +
     import org.slf4j.Logger;
    +  33   +
     import org.slf4j.LoggerFactory;
     34  
     
     35   @@ -110,17 +110,17 @@
          * The logger.
     44  
          */
    -  45  1
         private static final Logger LOGGER = Logger.getLogger(EvidenceCollection.class.getName());
    +  45  8
         private static final Logger LOGGER = LoggerFactory.getLogger(EvidenceCollection.class);
     46  
         /**
     47  
          * Used to iterate over highest confidence evidence contained in the collection.
     48  
          */
    -  49  61
         private static final Filter<Evidence> HIGHEST_CONFIDENCE = new Filter<Evidence>() {
    +  49  512
         private static final Filter<Evidence> HIGHEST_CONFIDENCE = new Filter<Evidence>() {
     50  
             public boolean passes(Evidence evidence) {
    -  51  60
                 return evidence.getConfidence() == Confidence.HIGHEST;
    +  51  504
                 return evidence.getConfidence() == Confidence.HIGHEST;
     52  
             }
     53   @@ -131,10 +131,10 @@
          * Used to iterate over high confidence evidence contained in the collection.
     56  
          */
    -  57  50
         private static final Filter<Evidence> HIGH_CONFIDENCE = new Filter<Evidence>() {
    +  57  328
         private static final Filter<Evidence> HIGH_CONFIDENCE = new Filter<Evidence>() {
     58  
             public boolean passes(Evidence evidence) {
    -  59  49
                 return evidence.getConfidence() == Confidence.HIGH;
    +  59  320
                 return evidence.getConfidence() == Confidence.HIGH;
     60  
             }
     61   @@ -145,10 +145,10 @@
          * Used to iterate over medium confidence evidence contained in the collection.
     64  
          */
    -  65  1
         private static final Filter<Evidence> MEDIUM_CONFIDENCE = new Filter<Evidence>() {
    +  65  8
         private static final Filter<Evidence> MEDIUM_CONFIDENCE = new Filter<Evidence>() {
     66  
             public boolean passes(Evidence evidence) {
    -  67  34
                 return evidence.getConfidence() == Confidence.MEDIUM;
    +  67  296
                 return evidence.getConfidence() == Confidence.MEDIUM;
     68  
             }
     69   @@ -159,10 +159,10 @@
          * Used to iterate over low confidence evidence contained in the collection.
     72  
          */
    -  73  1
         private static final Filter<Evidence> LOW_CONFIDENCE = new Filter<Evidence>() {
    +  73  8
         private static final Filter<Evidence> LOW_CONFIDENCE = new Filter<Evidence>() {
     74  
             public boolean passes(Evidence evidence) {
    -  75  34
                 return evidence.getConfidence() == Confidence.LOW;
    +  75  296
                 return evidence.getConfidence() == Confidence.LOW;
     76  
             }
     77   @@ -173,10 +173,10 @@
          * Used to iterate over evidence that has was used (aka read) from the collection.
     80  
          */
    -  81  1
         private static final Filter<Evidence> EVIDENCE_USED = new Filter<Evidence>() {
    +  81  8
         private static final Filter<Evidence> EVIDENCE_USED = new Filter<Evidence>() {
     82  
             public boolean passes(Evidence evidence) {
    -  83  1277
                 return evidence.isUsed();
    +  83  8640
                 return evidence.isUsed();
     84  
             }
     85   @@ -197,15 +197,15 @@
          */
     93  
         public final Iterable<Evidence> iterator(Confidence confidence) {
    -  94  20
             if (confidence == Confidence.HIGHEST) {
    -  95  6
                 return EvidenceCollection.HIGHEST_CONFIDENCE.filter(this.list);
    -  96  14
             } else if (confidence == Confidence.HIGH) {
    -  97  6
                 return EvidenceCollection.HIGH_CONFIDENCE.filter(this.list);
    -  98  8
             } else if (confidence == Confidence.MEDIUM) {
    -  99  4
                 return EvidenceCollection.MEDIUM_CONFIDENCE.filter(this.list);
    +  94  184
             if (confidence == Confidence.HIGHEST) {
    +  95  56
                 return EvidenceCollection.HIGHEST_CONFIDENCE.filter(this.list);
    +  96  128
             } else if (confidence == Confidence.HIGH) {
    +  97  48
                 return EvidenceCollection.HIGH_CONFIDENCE.filter(this.list);
    +  98  80
             } else if (confidence == Confidence.MEDIUM) {
    +  99  40
                 return EvidenceCollection.MEDIUM_CONFIDENCE.filter(this.list);
     100  
             } else {
    -  101  4
                 return EvidenceCollection.LOW_CONFIDENCE.filter(this.list);
    +  101  40
                 return EvidenceCollection.LOW_CONFIDENCE.filter(this.list);
     102  
             }
     103   @@ -234,10 +234,10 @@
          * Creates a new EvidenceCollection.
     115  
          */
    -  116  153
         public EvidenceCollection() {
    -  117  153
             list = new TreeSet<Evidence>();
    -  118  153
             weightedStrings = new HashSet<String>();
    -  119  153
         }
    +  116  1392
         public EvidenceCollection() {
    +  117  1392
             list = new TreeSet<Evidence>();
    +  118  1392
             weightedStrings = new HashSet<String>();
    +  119  1392
         }
     120  
     
     121   @@ -252,8 +252,8 @@
          */
     126  
         public void addEvidence(Evidence e) {
    -  127  15539
             list.add(e);
    -  128  15539
         }
    +  127  116856
             list.add(e);
    +  128  116856
         }
     129  
     
     130   @@ -274,27 +274,27 @@
          */
     138  
         public void addEvidence(String source, String name, String value, Confidence confidence) {
    -  139  15532
             final Evidence e = new Evidence(source, name, value, confidence);
    -  140  15532
             addEvidence(e);
    -  141  15532
         }
    +  139  116800
             final Evidence e = new Evidence(source, name, value, confidence);
    +  140  116800
             addEvidence(e);
    +  141  116800
         }
     142  
     
     143  
         /**
     144   -
          * Adds term to the weighting collection. The terms added here are used later to boost the score of other terms.
    +
          * Adds term to the weighting collection. The terms added here are used later to boost the score of other terms. This is a way
     145   -
          * This is a way of combining evidence from multiple sources to boost the confidence of the given evidence.
    +
          * of combining evidence from multiple sources to boost the confidence of the given evidence.
     146  
          *
     147   -
          * Example: The term 'Apache' is found in the manifest of a JAR and is added to the Collection. When we parse the
    +
          * Example: The term 'Apache' is found in the manifest of a JAR and is added to the Collection. When we parse the package
     148   -
          * package names within the JAR file we may add these package names to the "weighted" strings collection to boost
    +
          * names within the JAR file we may add these package names to the "weighted" strings collection to boost the score in the
     149   -
          * the score in the Lucene query. That way when we construct the Lucene query we find the term Apache in the
    +
          * Lucene query. That way when we construct the Lucene query we find the term Apache in the collection AND in the weighted
     150   -
          * collection AND in the weighted strings; as such, we will boost the confidence of the term Apache.
    +
          * strings; as such, we will boost the confidence of the term Apache.
     151  
          *
     152   @@ -303,16 +303,16 @@
          */
     154  
         public void addWeighting(String str) {
    -  155  15
             weightedStrings.add(str);
    -  156  15
         }
    +  155  120
             weightedStrings.add(str);
    +  156  120
         }
     157  
     
     158  
         /**
     159   -
          * Returns a set of Weightings - a list of terms that are believed to be of higher confidence when also found in
    +
          * Returns a set of Weightings - a list of terms that are believed to be of higher confidence when also found in another
     160   -
          * another location.
    +
          * location.
     161  
          *
     162   @@ -321,7 +321,7 @@
          */
     164  
         public Set<String> getWeighting() {
    -  165  13
             return weightedStrings;
    +  165  104
             return weightedStrings;
     166  
         }
     167   @@ -338,7 +338,7 @@
          */
     173  
         public Set<Evidence> getEvidence() {
    -  174  9
             return list;
    +  174  72
             return list;
     175  
         }
     176   @@ -389,18 +389,18 @@
          */
     203  
         public Set<Evidence> getEvidence(String source, String name) {
    -  204  8
             if (source == null || name == null) {
    +  204  64
             if (source == null || name == null) {
     205  0
                 return null;
     206  
             }
    -  207  8
             final Set<Evidence> ret = new HashSet<Evidence>();
    -  208  8
             for (Evidence e : list) {
    -  209  11
                 if (source.equals(e.getSource()) && name.equals(e.getName())) {
    -  210  5
                     ret.add(e);
    +  207  64
             final Set<Evidence> ret = new HashSet<Evidence>();
    +  208  64
             for (Evidence e : list) {
    +  209  88
                 if (source.equals(e.getSource()) && name.equals(e.getName())) {
    +  210  40
                     ret.add(e);
     211  
                 }
    -  212  11
             }
    -  213  8
             return ret;
    +  212  88
             }
    +  213  64
             return ret;
     214  
         }
     215   @@ -417,7 +417,7 @@
          */
     221  
         public Iterator<Evidence> iterator() {
    -  222  145
             return list.iterator();
    +  222  1048
             return list.iterator();
     223  
         }
     224   @@ -436,23 +436,23 @@
          */
     231  
         public boolean containsUsedString(String text) {
    -  232  133
             if (text == null) {
    +  232  952
             if (text == null) {
     233  0
                 return false;
     234  
             }
    -  235  133
             final String textToTest = text.toLowerCase();
    +  235  952
             final String textToTest = text.toLowerCase();
     236  
     
    -  237  133
             for (Evidence e : EvidenceCollection.EVIDENCE_USED.filter(this)) {
    +  237  952
             for (Evidence e : EvidenceCollection.EVIDENCE_USED.filter(this)) {
     238  
                 //TODO consider changing the regex to only compare alpha-numeric (i.e. strip everything else)
    -  239  768
                 final String value = urlCorrection(e.getValue().toLowerCase()).replaceAll("[\\s_-]", "");
    -  240  768
                 if (value.contains(textToTest)) {
    -  241  48
                     return true;
    +  239  5160
                 final String value = urlCorrection(e.getValue().toLowerCase()).replaceAll("[\\s_-]", "");
    +  240  5160
                 if (value.contains(textToTest)) {
    +  241  392
                     return true;
     242  
                 }
    -  243  720
             }
    -  244  85
             return false;
    +  243  4768
             }
    +  244  560
             return false;
     245  
         }
     246   @@ -503,13 +503,13 @@
          */
     273  
         public boolean contains(Confidence confidence) {
    -  274  14
             for (Evidence e : list) {
    -  275  62
                 if (e.getConfidence().equals(confidence)) {
    -  276  12
                     return true;
    +  274  112
             for (Evidence e : list) {
    +  275  488
                 if (e.getConfidence().equals(confidence)) {
    +  276  88
                     return true;
     277  
                 }
    -  278  50
             }
    -  279  2
             return false;
    +  278  400
             }
    +  279  24
             return false;
     280  
         }
     281   @@ -528,17 +528,17 @@
          */
     288  
         public static EvidenceCollection mergeUsed(EvidenceCollection... ec) {
    -  289  1
             final EvidenceCollection ret = new EvidenceCollection();
    -  290  4
             for (EvidenceCollection col : ec) {
    -  291  3
                 for (Evidence e : col.list) {
    -  292  2
                     if (e.isUsed()) {
    -  293  1
                         ret.addEvidence(e);
    +  289  8
             final EvidenceCollection ret = new EvidenceCollection();
    +  290  32
             for (EvidenceCollection col : ec) {
    +  291  24
                 for (Evidence e : col.list) {
    +  292  16
                     if (e.isUsed()) {
    +  293  8
                         ret.addEvidence(e);
     294  
                     }
    -  295  2
                 }
    +  295  16
                 }
     296  
             }
    -  297  1
             return ret;
    +  297  8
             return ret;
     298  
         }
     299   @@ -557,13 +557,13 @@
          */
     306  
         public static EvidenceCollection merge(EvidenceCollection... ec) {
    -  307  11
             final EvidenceCollection ret = new EvidenceCollection();
    -  308  44
             for (EvidenceCollection col : ec) {
    -  309  33
                 ret.list.addAll(col.list);
    -  310  33
                 ret.weightedStrings.addAll(col.weightedStrings);
    +  307  88
             final EvidenceCollection ret = new EvidenceCollection();
    +  308  352
             for (EvidenceCollection col : ec) {
    +  309  264
                 ret.list.addAll(col.list);
    +  310  264
                 ret.weightedStrings.addAll(col.weightedStrings);
     311  
             }
    -  312  11
             return ret;
    +  312  88
             return ret;
     313  
         }
     314   @@ -585,12 +585,13 @@  322  0
             final Set<Evidence> ret = new TreeSet<Evidence>();
     323  0
             for (EvidenceCollection col : ec) {
     324  0
                 for (Evidence e : col) {
    -  325  0
                     if (e.isUsed()) {
    -  326  0
                         final Evidence newEvidence = new Evidence(e.getSource(), e.getName(), e.getValue(), null);
    -  327  0
                         newEvidence.setUsed(true);
    -  328  0
                         ret.add(newEvidence);
    +  325   +
                     //if (e.isUsed()) {
    +  326  0
                     final Evidence newEvidence = new Evidence(e.getSource(), e.getName(), e.getValue(), null);
    +  327  0
                     newEvidence.setUsed(true);
    +  328  0
                     ret.add(newEvidence);
     329   -
                     }
    +
                     //}
     330  0
                 }
     331  
             }
    @@ -613,11 +614,11 @@
         @Override
     341  
         public String toString() {
    -  342  10
             final StringBuilder sb = new StringBuilder();
    -  343  10
             for (Evidence e : this.list) {
    -  344  35
                 sb.append(e.getValue()).append(' ');
    -  345  35
             }
    -  346  10
             return sb.toString();
    +  342  264
             final StringBuilder sb = new StringBuilder();
    +  343  264
             for (Evidence e : this.list) {
    +  344  512
                 sb.append(e.getValue()).append(' ');
    +  345  512
             }
    +  346  264
             return sb.toString();
     347  
         }
     348   @@ -634,7 +635,7 @@
          */
     354  
         public int size() {
    -  355  13
             return list.size();
    +  355  96
             return list.size();
     356  
         }
     357   @@ -644,15 +645,15 @@  359  
          * <p>
     360   -
          * Takes a string that may contain a fully qualified domain and it will return the string having removed the query
    +
          * Takes a string that may contain a fully qualified domain and it will return the string having removed the query string, the
     361   -
          * string, the protocol, the sub-domain of 'www', and the file extension of the path.</p>
    +
          * protocol, the sub-domain of 'www', and the file extension of the path.</p>
     362  
          * <p>
     363   -
          * This is useful for checking if the evidence contains a specific string. The presence of the protocol, file
    +
          * This is useful for checking if the evidence contains a specific string. The presence of the protocol, file extension, etc.
     364   -
          * extension, etc. may produce false positives.
    +
          * may produce false positives.
     365  
          *
     366   @@ -677,22 +678,22 @@
          */
     376  
         private String urlCorrection(String value) {
    -  377  768
             if (value == null || !UrlStringUtils.containsUrl(value)) {
    -  378  749
                 return value;
    +  377  5160
             if (value == null || !UrlStringUtils.containsUrl(value)) {
    +  378  5008
                 return value;
     379  
             }
    -  380  19
             final StringBuilder sb = new StringBuilder(value.length());
    -  381  19
             final String[] parts = value.split("\\s");
    -  382  38
             for (String part : parts) {
    -  383  19
                 if (UrlStringUtils.isUrl(part)) {
    +  380  152
             final StringBuilder sb = new StringBuilder(value.length());
    +  381  152
             final String[] parts = value.split("\\s");
    +  382  304
             for (String part : parts) {
    +  383  152
                 if (UrlStringUtils.isUrl(part)) {
     384  
                     try {
    -  385  19
                         final List<String> data = UrlStringUtils.extractImportantUrlData(part);
    -  386  19
                         sb.append(' ').append(StringUtils.join(data, ' '));
    +  385  152
                         final List<String> data = UrlStringUtils.extractImportantUrlData(part);
    +  386  152
                         sb.append(' ').append(StringUtils.join(data, ' '));
     387  0
                     } catch (MalformedURLException ex) {
    -  388  0
                         LOGGER.log(Level.FINE, "error parsing " + part, ex);
    +  388  0
                         LOGGER.debug("error parsing {}", part, ex);
     389  0
                         sb.append(' ').append(part);
    -  390  19
                     }
    +  390  152
                     }
     391  
                 } else {
     392  0
                     sb.append(' ').append(part);
    @@ -700,13 +701,13 @@
                 }
     394  
             }
    -  395  19
             return sb.toString().trim();
    +  395  152
             return sb.toString().trim();
     396  
         }
     397  
     }
    - + 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 b96c3bfaf..6db5d2650 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  27
     public class Identifier implements Serializable, Comparable<Identifier> {
    +  26  240
     public class Identifier implements Serializable, Comparable<Identifier> {
     27  
     
     28   @@ -100,11 +100,11 @@
          * @param url the identifier url.
     43  
          */
    -  44  26
         public Identifier(String type, String value, String url) {
    -  45  26
             this.type = type;
    -  46  26
             this.value = value;
    -  47  26
             this.url = url;
    -  48  26
         }
    +  44  216
         public Identifier(String type, String value, String url) {
    +  45  216
             this.type = type;
    +  46  216
             this.value = value;
    +  47  216
             this.url = url;
    +  48  216
         }
     49  
     
     50   @@ -169,8 +169,8 @@
          */
     82  
         public void setConfidence(Confidence confidence) {
    -  83  4
             this.confidence = confidence;
    -  84  4
         }
    +  83  40
             this.confidence = confidence;
    +  84  40
         }
     85  
     
     86   @@ -195,7 +195,7 @@
          */
     96  
         public String getValue() {
    -  97  115
             return value;
    +  97  1248
             return value;
     98  
         }
     99   @@ -277,7 +277,7 @@
          */
     140  
         public String getType() {
    -  141  106
             return type;
    +  141  1248
             return type;
     142  
         }
     143   @@ -373,10 +373,10 @@
         @Override
     196  
         public int hashCode() {
    -  197  10
             int hash = 5;
    -  198  10
             hash = 53 * hash + (this.value != null ? this.value.hashCode() : 0);
    -  199  10
             hash = 53 * hash + (this.type != null ? this.type.hashCode() : 0);
    -  200  10
             return hash;
    +  197  120
             int hash = 5;
    +  198  120
             hash = 53 * hash + (this.value != null ? this.value.hashCode() : 0);
    +  199  120
             hash = 53 * hash + (this.type != null ? this.type.hashCode() : 0);
    +  200  120
             return hash;
     201  
         }
     202   @@ -414,17 +414,17 @@
          */
     219  
         public int compareTo(Identifier o) {
    -  220  29
             if (o == null) {
    +  220  256
             if (o == null) {
     221  0
                 return -1;
     222  
             }
    -  223  29
             return this.value.compareTo(o.value);
    +  223  256
             return this.value.compareTo(o.value);
     224  
         }
     225  
     }
    - + 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 5aedf53c5..a6b8d6687 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Reference.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Reference.html @@ -69,7 +69,7 @@
      * @author Jeremy Long
     26  
      */
    -  27  502
     public class Reference implements Serializable, Comparable<Reference> {
    +  27  4096
     public class Reference implements Serializable, Comparable<Reference> {
     28  
     
     29   @@ -119,8 +119,8 @@
          */
     52  
         public void setName(String name) {
    -  53  156
             this.name = name;
    -  54  156
         }
    +  53  1264
             this.name = name;
    +  54  1264
         }
     55  
         /**
     56   @@ -160,8 +160,8 @@
          */
     74  
         public void setUrl(String url) {
    -  75  156
             this.url = url;
    -  76  156
         }
    +  75  1264
             this.url = url;
    +  76  1264
         }
     77  
         /**
     78   @@ -201,8 +201,8 @@
          */
     96  
         public void setSource(String source) {
    -  97  156
             this.source = source;
    -  98  156
         }
    +  97  1264
             this.source = source;
    +  98  1264
         }
     99  
     
     100   @@ -262,10 +262,10 @@
          */
     136  
         public int compareTo(Reference o) {
    -  137  346
             if (source.equals(o.source)) {
    -  138  105
                 if (name.equals(o.name)) {
    -  139  34
                     if (url.equals(o.url)) {
    -  140  34
                         return 0; //they are equal
    +  137  2832
             if (source.equals(o.source)) {
    +  138  832
                 if (name.equals(o.name)) {
    +  139  272
                     if (url.equals(o.url)) {
    +  140  272
                         return 0; //they are equal
     141  
                     } else {
     142  0
                         return url.compareTo(o.url);
    @@ -273,12 +273,12 @@
                     }
     144  
                 } else {
    -  145  71
                     return name.compareTo(o.name);
    +  145  560
                     return name.compareTo(o.name);
     146  
                 }
     147  
             } else {
    -  148  241
                 return source.compareTo(o.source);
    +  148  2000
                 return source.compareTo(o.source);
     149  
             }
     150   @@ -287,6 +287,6 @@
     }
    - + 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 92444cabb..2a77c7745 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Vulnerability.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.dependency.Vulnerability.html @@ -75,7 +75,7 @@
      * @author Jeremy Long
     29  
      */
    -  30  36
     public class Vulnerability implements Serializable, Comparable<Vulnerability> {
    +  30  288
     public class Vulnerability implements Serializable, Comparable<Vulnerability> {
     31  
     
     32   @@ -108,7 +108,7 @@
          */
     46  
         public String getName() {
    -  47  53
             return name;
    +  47  424
             return name;
     48  
         }
     49   @@ -125,8 +125,8 @@
          */
     55  
         public void setName(String name) {
    -  56  36
             this.name = name;
    -  57  36
         }
    +  56  288
             this.name = name;
    +  57  288
         }
     58  
         /**
     59   @@ -166,15 +166,15 @@
          */
     77  
         public void setDescription(String description) {
    -  78  35
             this.description = description;
    -  79  35
         }
    +  78  280
             this.description = description;
    +  79  280
         }
     80  
         /**
     81  
          * References for this vulnerability.
     82  
          */
    -  83  36
         private SortedSet<Reference> references = new TreeSet<Reference>();
    +  83  288
         private SortedSet<Reference> references = new TreeSet<Reference>();
     84  
     
     85   @@ -222,8 +222,8 @@
          */
     108  
         public void addReference(Reference ref) {
    -  109  90
             this.references.add(ref);
    -  110  90
         }
    +  109  720
             this.references.add(ref);
    +  110  720
         }
     111  
     
     112   @@ -242,19 +242,19 @@
          */
     119  
         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
         }
    +  120  544
             final Reference ref = new Reference();
    +  121  544
             ref.setSource(referenceSource);
    +  122  544
             ref.setName(referenceName);
    +  123  544
             ref.setUrl(referenceUrl);
    +  124  544
             this.references.add(ref);
    +  125  544
         }
     126  
         /**
     127  
          * A set of vulnerable software.
     128  
          */
    -  129  36
         private SortedSet<VulnerableSoftware> vulnerableSoftware = new TreeSet<VulnerableSoftware>();
    +  129  288
         private SortedSet<VulnerableSoftware> vulnerableSoftware = new TreeSet<VulnerableSoftware>();
     130  
     
     131   @@ -304,7 +304,7 @@
          */
     155  
         public boolean addVulnerableSoftware(String cpe) {
    -  156  842
             return addVulnerableSoftware(cpe, null);
    +  156  6736
             return addVulnerableSoftware(cpe, null);
     157  
         }
     158   @@ -325,13 +325,13 @@
          */
     166  
         public boolean addVulnerableSoftware(String cpe, String previousVersion) {
    -  167  850
             final VulnerableSoftware vs = new VulnerableSoftware();
    -  168  850
             vs.setCpe(cpe);
    -  169  850
             if (previousVersion != null) {
    -  170  8
                 vs.setPreviousVersion(previousVersion);
    +  167  6800
             final VulnerableSoftware vs = new VulnerableSoftware();
    +  168  6800
             vs.setCpe(cpe);
    +  169  6800
             if (previousVersion != null) {
    +  170  64
                 vs.setPreviousVersion(previousVersion);
     171  
             }
    -  172  850
             return updateVulnerableSoftware(vs);
    +  172  6800
             return updateVulnerableSoftware(vs);
     173  
         }
     174   @@ -350,11 +350,11 @@
          */
     181  
         public boolean updateVulnerableSoftware(VulnerableSoftware vulnSoftware) {
    -  182  850
             if (vulnerableSoftware.contains(vulnSoftware)) {
    +  182  6800
             if (vulnerableSoftware.contains(vulnSoftware)) {
     183  0
                 vulnerableSoftware.remove(vulnSoftware);
     184  
             }
    -  185  850
             return vulnerableSoftware.add(vulnSoftware);
    +  185  6800
             return vulnerableSoftware.add(vulnSoftware);
     186  
         }
     187   @@ -379,7 +379,7 @@
          */
     197  
         public String getCwe() {
    -  198  2
             return cwe;
    +  198  16
             return cwe;
     199  
         }
     200   @@ -396,8 +396,8 @@
          */
     206  
         public void setCwe(String cwe) {
    -  207  28
             this.cwe = cwe;
    -  208  28
         }
    +  207  224
             this.cwe = cwe;
    +  208  224
         }
     209  
         /**
     210   @@ -420,7 +420,7 @@
          */
     219  
         public float getCvssScore() {
    -  220  3
             return cvssScore;
    +  220  24
             return cvssScore;
     221  
         }
     222   @@ -437,8 +437,8 @@
          */
     228  
         public void setCvssScore(float cvssScore) {
    -  229  35
             this.cvssScore = cvssScore;
    -  230  35
         }
    +  229  280
             this.cvssScore = cvssScore;
    +  230  280
         }
     231  
         /**
     232   @@ -478,8 +478,8 @@
          */
     250  
         public void setCvssAccessVector(String cvssAccessVector) {
    -  251  34
             this.cvssAccessVector = cvssAccessVector;
    -  252  34
         }
    +  251  272
             this.cvssAccessVector = cvssAccessVector;
    +  252  272
         }
     253  
         /**
     254   @@ -519,8 +519,8 @@
          */
     272  
         public void setCvssAccessComplexity(String cvssAccessComplexity) {
    -  273  34
             this.cvssAccessComplexity = cvssAccessComplexity;
    -  274  34
         }
    +  273  272
             this.cvssAccessComplexity = cvssAccessComplexity;
    +  274  272
         }
     275  
         /**
     276   @@ -560,8 +560,8 @@
          */
     294  
         public void setCvssAuthentication(String cvssAuthentication) {
    -  295  34
             this.cvssAuthentication = cvssAuthentication;
    -  296  34
         }
    +  295  272
             this.cvssAuthentication = cvssAuthentication;
    +  296  272
         }
     297  
         /**
     298   @@ -601,8 +601,8 @@
          */
     316  
         public void setCvssConfidentialityImpact(String cvssConfidentialityImpact) {
    -  317  34
             this.cvssConfidentialityImpact = cvssConfidentialityImpact;
    -  318  34
         }
    +  317  272
             this.cvssConfidentialityImpact = cvssConfidentialityImpact;
    +  318  272
         }
     319  
         /**
     320   @@ -642,8 +642,8 @@
          */
     338  
         public void setCvssIntegrityImpact(String cvssIntegrityImpact) {
    -  339  34
             this.cvssIntegrityImpact = cvssIntegrityImpact;
    -  340  34
         }
    +  339  272
             this.cvssIntegrityImpact = cvssIntegrityImpact;
    +  340  272
         }
     341  
         /**
     342   @@ -683,8 +683,8 @@
          */
     360  
         public void setCvssAvailabilityImpact(String cvssAvailabilityImpact) {
    -  361  34
             this.cvssAvailabilityImpact = cvssAvailabilityImpact;
    -  362  34
         }
    +  361  272
             this.cvssAvailabilityImpact = cvssAvailabilityImpact;
    +  362  272
         }
     363  
     
     364   @@ -713,9 +713,9 @@
         @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;
    +  381  64
             int hash = 5;
    +  382  64
             hash = 41 * hash + (this.name != null ? this.name.hashCode() : 0);
    +  383  64
             return hash;
     384  
         }
     385   @@ -775,9 +775,9 @@
          */
     413  
         public void setMatchedCPE(String cpeId, String previous) {
    -  414  8
             matchedCPE = cpeId;
    -  415  8
             matchedAllPreviousCPE = previous;
    -  416  8
         }
    +  414  64
             matchedCPE = cpeId;
    +  415  64
             matchedAllPreviousCPE = previous;
    +  416  64
         }
     417  
     
     418   @@ -833,6 +833,6 @@
     }
    - + 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 0154c891f..991e0410b 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  119
     public class VulnerabilityComparator implements Comparator<Vulnerability>, Serializable {
    +  28  1064
     public class VulnerabilityComparator implements Comparator<Vulnerability>, Serializable {
     29  
     
     30   @@ -100,13 +100,13 @@
          */
     42  
         public int compare(Vulnerability o1, Vulnerability o2) {
    -  43  25
             return o2.getName().compareTo(o1.getName());
    +  43  200
             return o2.getName().compareTo(o1.getName());
     44  
         }
     45  
     }
    - + 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 ce24976e2..c11af51ee 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.263
    VulnerableSoftware
    68%
    68/99
    72%
    52/72
    3.15
     
    @@ -62,11 +62,11 @@  22  
     import java.net.URLDecoder;
     23   -
     import java.util.logging.Level;
    -  24   -
     import java.util.logging.Logger;
    -  25  
     import org.owasp.dependencycheck.data.cpe.IndexEntry;
    +  24   +
     import org.slf4j.Logger;
    +  25   +
     import org.slf4j.LoggerFactory;
     26  
     
     27   @@ -79,7 +79,7 @@
      * @author Jeremy Long
     31  
      */
    -  32  11337
     public class VulnerableSoftware extends IndexEntry implements Serializable, Comparable<VulnerableSoftware> {
    +  32  91872
     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 = Logger.getLogger(VulnerableSoftware.class.getName());
    +  37  8
         private static final Logger LOGGER = LoggerFactory.getLogger(VulnerableSoftware.class);
     38  
         /**
     39   @@ -113,543 +113,561 @@
         public void setCpe(String cpe) {
     49  
             try {
    -  50  936
                 parseName(cpe);
    +  50  7736
                 parseName(cpe);
     51  0
             } catch (UnsupportedEncodingException ex) {
    -  52  0
                 final String msg = String.format("Character encoding is unsupported for CPE '%s'.", cpe);
    -  53  0
                 LOGGER.log(Level.WARNING, msg);
    -  54  0
                 LOGGER.log(Level.FINE, null, ex);
    -  55  0
                 setName(cpe);
    -  56  936
             }
    -  57  936
         }
    +  52  0
                 LOGGER.warn("Character encoding is unsupported for CPE '{}'.", cpe);
    +  53  0
                 LOGGER.debug("", ex);
    +  54  0
                 setName(cpe);
    +  55  7736
             }
    +  56  7736
         }
    +  57   +
     
     58   -
     
    +
         /**
     59   -
         /**
    +
          * <p>
     60   -
          * <p>
    +
          * Parses a name attribute value, from the cpe.xml, into its corresponding parts: vendor, product, version, update.</p>
     61   -
          * Parses a name attribute value, from the cpe.xml, into its corresponding parts: vendor, product, version,
    +
          * <p>
     62   -
          * revision.</p>
    -  63   -
          * <p>
    -  64  
          * Example:</p>
    -  65   +  63  
          * <code>&nbsp;&nbsp;&nbsp;cpe:/a:apache:struts:1.1:rc2</code>
    -  66   +  64  
          *
    -  67   +  65  
          * <p>
    -  68   +  66  
          * Results in:</p> <ul> <li>Vendor: apache</li> <li>Product: struts</li>
    -  69   +  67  
          * <li>Version: 1.1</li> <li>Revision: rc2</li> </ul>
    -  70   +  68  
          *
    -  71   +  69  
          * @param cpeName the cpe name
    -  72   +  70  
          * @throws UnsupportedEncodingException should never be thrown...
    +  71   +
          */
    +  72   +
         @Override
     73   -
          */
    -  74   -
         @Override
    -  75  
         public void parseName(String cpeName) throws UnsupportedEncodingException {
    -  76  1333
             this.name = cpeName;
    -  77  1333
             if (cpeName != null && cpeName.length() > 7) {
    -  78  1333
                 final String[] data = cpeName.substring(7).split(":");
    -  79  1333
                 if (data.length >= 1) {
    -  80  1333
                     this.setVendor(urlDecode(data[0]));
    -  81   +  74  11840
             this.name = cpeName;
    +  75  11840
             if (cpeName != null && cpeName.length() > 7) {
    +  76  11840
                 final String[] data = cpeName.substring(7).split(":");
    +  77  11840
                 if (data.length >= 1) {
    +  78  11840
                     this.setVendor(urlDecode(data[0]));
    +  79  
                 }
    -  82  1333
                 if (data.length >= 2) {
    -  83  1333
                     this.setProduct(urlDecode(data[1]));
    -  84   +  80  11840
                 if (data.length >= 2) {
    +  81  11840
                     this.setProduct(urlDecode(data[1]));
    +  82  
                 }
    -  85  1333
                 if (data.length >= 3) {
    -  86  1333
                     version = urlDecode(data[2]);
    -  87   +  83  11840
                 if (data.length >= 3) {
    +  84  11840
                     version = urlDecode(data[2]);
    +  85  
                 }
    -  88  1333
                 if (data.length >= 4) {
    -  89  249
                     revision = urlDecode(data[3]);
    -  90   +  86  11840
                 if (data.length >= 4) {
    +  87  1992
                     update = urlDecode(data[3]);
    +  88  
                 }
    -  91  1333
                 if (data.length >= 5) {
    -  92  0
                     edition = urlDecode(data[4]);
    -  93   +  89  11840
                 if (data.length >= 5) {
    +  90  0
                     edition = urlDecode(data[4]);
    +  91  
                 }
    +  92   +
             }
    +  93  11840
         }
     94   -
             }
    -  95  1333
         }
    -  96  
         /**
    -  97   +  95  
          * If present, indicates that previous version are vulnerable.
    -  98   +  96  
          */
    -  99   +  97  
         private String previousVersion;
    +  98   +
     
    +  99   +
         /**
     100   -
     
    -  101   -
         /**
    -  102  
          * Indicates if previous versions of this software are vulnerable.
    -  103   +  101  
          *
    -  104   +  102  
          * @return if previous versions of this software are vulnerable
    -  105   +  103  
          */
    -  106   +  104  
         public boolean hasPreviousVersion() {
    -  107  0
             return previousVersion != null;
    +  105  0
             return previousVersion != null;
    +  106   +
         }
    +  107   +
     
     108   -
         }
    +
         /**
     109   -
     
    -  110   -
         /**
    -  111  
          * Get the value of previousVersion.
    -  112   +  110  
          *
    -  113   +  111  
          * @return the value of previousVersion
    -  114   +  112  
          */
    -  115   +  113  
         public String getPreviousVersion() {
    -  116  0
             return previousVersion;
    +  114  0
             return previousVersion;
    +  115   +
         }
    +  116   +
     
     117   -
         }
    +
         /**
     118   -
     
    -  119   -
         /**
    -  120  
          * Set the value of previousVersion.
    -  121   +  119  
          *
    -  122   +  120  
          * @param previousVersion new value of previousVersion
    -  123   +  121  
          */
    -  124   +  122  
         public void setPreviousVersion(String previousVersion) {
    -  125  9
             this.previousVersion = previousVersion;
    -  126  9
         }
    +  123  72
             this.previousVersion = previousVersion;
    +  124  72
         }
    +  125   +
     
    +  126   +
         /**
     127   -
     
    -  128   -
         /**
    -  129  
          * Standard equals implementation to compare this VulnerableSoftware to another object.
    -  130   +  128  
          *
    -  131   +  129  
          * @param obj the object to compare
    -  132   +  130  
          * @return whether or not the objects are equal
    +  131   +
          */
    +  132   +
         @Override
     133   -
          */
    -  134   -
         @Override
    -  135  
         public boolean equals(Object obj) {
    -  136  1
             if (obj == null) {
    -  137  0
                 return false;
    -  138   +  134  8
             if (obj == null) {
    +  135  0
                 return false;
    +  136  
             }
    -  139  1
             if (getClass() != obj.getClass()) {
    -  140  0
                 return false;
    -  141   +  137  8
             if (getClass() != obj.getClass()) {
    +  138  0
                 return false;
    +  139  
             }
    -  142  1
             final VulnerableSoftware other = (VulnerableSoftware) obj;
    -  143  1
             if ((this.getName() == null) ? (other.getName() != null) : !this.getName().equals(other.getName())) {
    -  144  1
                 return false;
    +  140  8
             final VulnerableSoftware other = (VulnerableSoftware) obj;
    +  141  8
             if ((this.getName() == null) ? (other.getName() != null) : !this.getName().equals(other.getName())) {
    +  142  8
                 return false;
    +  143   +
             }
    +  144  0
             return true;
     145   -
             }
    -  146  0
             return true;
    +
         }
    +  146   +
     
     147   -
         }
    +
         /**
     148   -
     
    -  149   -
         /**
    -  150  
          * Standard implementation of hashCode.
    -  151   +  149  
          *
    -  152   +  150  
          * @return the hashCode for the object
    +  151   +
          */
    +  152   +
         @Override
     153   -
          */
    -  154   -
         @Override
    -  155  
         public int hashCode() {
    -  156  82
             int hash = 7;
    -  157  82
             hash = 83 * hash + (this.getName() != null ? this.getName().hashCode() : 0);
    -  158  82
             return hash;
    +  154  920
             int hash = 7;
    +  155  920
             hash = 83 * hash + (this.getName() != null ? this.getName().hashCode() : 0);
    +  156  920
             return hash;
    +  157   +
         }
    +  158   +
     
     159   -
         }
    +
         /**
     160   -
     
    -  161   -
         /**
    -  162  
          * Standard toString() implementation display the name and whether or not previous versions are also affected.
    -  163   +  161  
          *
    -  164   +  162  
          * @return a string representation of the object
    +  163   +
          */
    +  164   +
         @Override
     165   -
          */
    -  166   -
         @Override
    -  167  
         public String toString() {
    -  168  0
             return "VulnerableSoftware{ name=" + name + ", previousVersion=" + previousVersion + '}';
    +  166  0
             return "VulnerableSoftware{ name=" + name + ", previousVersion=" + previousVersion + '}';
    +  167   +
         }
    +  168   +
     
     169   -
         }
    +
         /**
     170   -
     
    -  171   -
         /**
    -  172  
          * Implementation of the comparable interface.
    -  173   +  171  
          *
    -  174   +  172  
          * @param vs the VulnerableSoftware to compare
    -  175   +  173  
          * @return an integer indicating the ordering of the two objects
    -  176   +  174  
          */
    -  177   +  175  
         @Override
    -  178   +  176  
         public int compareTo(VulnerableSoftware vs) {
    -  179  10006
             int result = 0;
    -  180  10006
             final String[] left = this.getName().split(":");
    -  181  10006
             final String[] right = vs.getName().split(":");
    -  182  10006
             final int max = (left.length <= right.length) ? left.length : right.length;
    -  183  10006
             if (max > 0) {
    -  184  60251
                 for (int i = 0; result == 0 && i < max; i++) {
    -  185  50245
                     final String[] subLeft = left[i].split("\\.");
    -  186  50245
                     final String[] subRight = right[i].split("\\.");
    -  187  50245
                     final int subMax = (subLeft.length <= subRight.length) ? subLeft.length : subRight.length;
    -  188  50245
                     if (subMax > 0) {
    -  189  114648
                         for (int x = 0; result == 0 && x < subMax; x++) {
    -  190  64403
                             if (isPositiveInteger(subLeft[x]) && isPositiveInteger(subRight[x])) {
    -  191   +  177  80048
             int result = 0;
    +  178  80048
             final String[] left = this.getName().split(":");
    +  179  80048
             final String[] right = vs.getName().split(":");
    +  180  80048
             final int max = (left.length <= right.length) ? left.length : right.length;
    +  181  80048
             if (max > 0) {
    +  182  482008
                 for (int i = 0; result == 0 && i < max; i++) {
    +  183  401960
                     final String[] subLeft = left[i].split("\\.");
    +  184  401960
                     final String[] subRight = right[i].split("\\.");
    +  185  401960
                     final int subMax = (subLeft.length <= subRight.length) ? subLeft.length : subRight.length;
    +  186  401960
                     if (subMax > 0) {
    +  187  917184
                         for (int x = 0; result == 0 && x < subMax; x++) {
    +  188  515224
                             if (isPositiveInteger(subLeft[x]) && isPositiveInteger(subRight[x])) {
    +  189  
                                 try {
    -  192  23452
                                     result = Long.valueOf(subLeft[x]).compareTo(Long.valueOf(subRight[x]));
    -  193   +  190  187616
                                     result = Long.valueOf(subLeft[x]).compareTo(Long.valueOf(subRight[x]));
    +  191  
     //                                final long iLeft = Long.parseLong(subLeft[x]);
    -  194   +  192  
     //                                final long iRight = Long.parseLong(subRight[x]);
    -  195   +  193  
     //                                if (iLeft != iRight) {
    -  196   +  194  
     //                                    if (iLeft > iRight) {
    -  197   +  195  
     //                                        result = 2;
    -  198   +  196  
     //                                    } else {
    -  199   +  197  
     //                                        result = -2;
    -  200   +  198  
     //                                    }
    -  201   +  199  
     //                                }
    -  202  0
                                 } catch (NumberFormatException ex) {
    -  203   +  200  0
                                 } catch (NumberFormatException ex) {
    +  201  
                                     //ignore the exception - they obviously aren't numbers
    -  204  0
                                     if (!subLeft[x].equalsIgnoreCase(subRight[x])) {
    -  205  0
                                         result = subLeft[x].compareToIgnoreCase(subRight[x]);
    -  206   +  202  0
                                     if (!subLeft[x].equalsIgnoreCase(subRight[x])) {
    +  203  0
                                         result = subLeft[x].compareToIgnoreCase(subRight[x]);
    +  204  
                                     }
    -  207  23452
                                 }
    -  208   +  205  187616
                                 }
    +  206  
                             } else {
    -  209  40951
                                 result = subLeft[x].compareToIgnoreCase(subRight[x]);
    -  210   +  207  327608
                                 result = subLeft[x].compareToIgnoreCase(subRight[x]);
    +  208  
                             }
    -  211   +  209  
                         }
    -  212  50245
                         if (result == 0) {
    -  213  40464
                             if (subLeft.length > subRight.length) {
    -  214  114
                                 result = 2;
    -  215   +  210  401960
                         if (result == 0) {
    +  211  323712
                             if (subLeft.length > subRight.length) {
    +  212  912
                                 result = 2;
    +  213  
                             }
    -  216  40464
                             if (subRight.length > subLeft.length) {
    -  217  7
                                 result = -2;
    +  214  323712
                             if (subRight.length > subLeft.length) {
    +  215  56
                                 result = -2;
    +  216   +
                             }
    +  217   +
                         }
     218   -
                             }
    -  219   -
                         }
    -  220  
                     } else {
    -  221  0
                         result = left[i].compareToIgnoreCase(right[i]);
    -  222   +  219  0
                         result = left[i].compareToIgnoreCase(right[i]);
    +  220  
                     }
    -  223   +  221  
                 }
    -  224  10006
                 if (result == 0) {
    -  225  104
                     if (left.length > right.length) {
    -  226  68
                         result = 2;
    -  227   +  222  80048
                 if (result == 0) {
    +  223  832
                     if (left.length > right.length) {
    +  224  544
                         result = 2;
    +  225  
                     }
    -  228  104
                     if (right.length > left.length) {
    -  229  10
                         result = -2;
    +  226  832
                     if (right.length > left.length) {
    +  227  80
                         result = -2;
    +  228   +
                     }
    +  229   +
                 }
     230   -
                     }
    -  231   -
                 }
    -  232  
             } else {
    -  233  0
                 result = this.getName().compareToIgnoreCase(vs.getName());
    +  231  0
                 result = this.getName().compareToIgnoreCase(vs.getName());
    +  232   +
             }
    +  233  80048
             return result;
     234   -
             }
    -  235  10006
             return result;
    +
         }
    +  235   +
     
     236   -
         }
    +
         /**
     237   -
     
    -  238   -
         /**
    -  239  
          * Determines if the string passed in is a positive integer.
    -  240   +  238  
          *
    -  241   +  239  
          * @param str the string to test
    -  242   +  240  
          * @return true if the string only contains 0-9, otherwise false.
    -  243   +  241  
          */
    -  244   +  242  
         private static boolean isPositiveInteger(final String str) {
    -  245  87927
             if (str == null || str.isEmpty()) {
    -  246  14
                 return false;
    -  247   +  243  703416
             if (str == null || str.isEmpty()) {
    +  244  112
                 return false;
    +  245  
             }
    -  248  142898
             for (int i = 0; i < str.length(); i++) {
    -  249  95922
                 final char c = str.charAt(i);
    -  250  95922
                 if (c < '0' || c > '9') {
    -  251  40937
                     return false;
    -  252   +  246  1143184
             for (int i = 0; i < str.length(); i++) {
    +  247  767376
                 final char c = str.charAt(i);
    +  248  767376
                 if (c < '0' || c > '9') {
    +  249  327496
                     return false;
    +  250  
                 }
    -  253   +  251  
             }
    -  254  46976
             return true;
    +  252  375808
             return true;
    +  253   +
         }
    +  254   +
         /**
     255   -
         }
    -  256   -
         /**
    -  257  
          * The name of the cpe.
    -  258   +  256  
          */
    -  259   +  257  
         private String name;
    +  258   +
     
    +  259   +
         /**
     260   -
     
    -  261   -
         /**
    -  262  
          * Get the value of name.
    -  263   +  261  
          *
    -  264   +  262  
          * @return the value of name
    -  265   +  263  
          */
    -  266   +  264  
         public String getName() {
    -  267  20195
             return name;
    +  265  162088
             return name;
    +  266   +
         }
    +  267   +
     
     268   -
         }
    +
         /**
     269   -
     
    -  270   -
         /**
    -  271  
          * Set the value of name.
    -  272   +  270  
          *
    -  273   +  271  
          * @param name new value of name
    -  274   +  272  
          */
    -  275   +  273  
         public void setName(String name) {
    -  276  0
             this.name = name;
    -  277  0
         }
    -  278   +  274  0
             this.name = name;
    +  275  0
         }
    +  276  
         /**
    -  279   +  277  
          * The product version number.
    -  280   +  278  
          */
    -  281   +  279  
         private String version;
    +  280   +
     
    +  281   +
         /**
     282   -
     
    -  283   -
         /**
    -  284  
          * Get the value of version.
    -  285   +  283  
          *
    -  286   +  284  
          * @return the value of version
    -  287   +  285  
          */
    -  288   +  286  
         public String getVersion() {
    -  289  1494
             return version;
    +  287  15656
             return version;
    +  288   +
         }
    +  289   +
     
     290   -
         }
    +
         /**
     291   -
     
    -  292   -
         /**
    -  293  
          * Set the value of version.
    -  294   +  292  
          *
    -  295   +  293  
          * @param version new value of version
    -  296   +  294  
          */
    -  297   +  295  
         public void setVersion(String version) {
    -  298  0
             this.version = version;
    -  299  0
         }
    +  296  0
             this.version = version;
    +  297  0
         }
    +  298   +
         /**
    +  299   +
          * The product update version.
     300   -
         /**
    +
          */
     301   -
          * The product revision version.
    +
         private String update;
     302   -
          */
    +
     
     303   -
         private String revision;
    +
         /**
     304   -
     
    +
          * Get the value of update.
     305   -
         /**
    +
          *
     306   -
          * Get the value of revision.
    +
          * @return the value of update
     307   -
          *
    +
          */
     308   -
          * @return the value of revision
    -  309   -
          */
    +
         public String getUpdate() {
    +  309  11672
             return update;
     310   -
         public String getRevision() {
    -  311  1222
             return revision;
    +
         }
    +  311   +
     
     312   -
         }
    +
         /**
     313   -
     
    +
          * Set the value of update.
     314   -
         /**
    +
          *
     315   -
          * Set the value of revision.
    +
          * @param update new value of update
     316   -
          *
    +
          */
     317   -
          * @param revision new value of revision
    -  318   -
          */
    -  319   -
         public void setRevision(String revision) {
    -  320  0
             this.revision = revision;
    -  321  0
         }
    -  322   +
         public void setUpdate(String update) {
    +  318  0
             this.update = update;
    +  319  0
         }
    +  320  
         /**
    -  323   +  321  
          * The product edition.
    -  324   +  322  
          */
    -  325   +  323  
         private String edition;
    +  324   +
     
    +  325   +
         /**
     326   -
     
    -  327   -
         /**
    -  328  
          * Get the value of edition.
    -  329   +  327  
          *
    -  330   +  328  
          * @return the value of edition
    -  331   +  329  
          */
    -  332   +  330  
         public String getEdition() {
    -  333  0
             return edition;
    +  331  0
             return edition;
    +  332   +
         }
    +  333   +
     
     334   -
         }
    +
         /**
     335   -
     
    -  336   -
         /**
    -  337  
          * Set the value of edition.
    -  338   +  336  
          *
    -  339   +  337  
          * @param edition new value of edition
    -  340   +  338  
          */
    -  341   +  339  
         public void setEdition(String edition) {
    -  342  0
             this.edition = edition;
    -  343  0
         }
    -  344   +  340  0
             this.edition = edition;
    +  341  0
         }
    +  342  
     
    -  345   +  343  
         /**
    -  346   +  344  
          * Replaces '+' with '%2B' and then URL Decodes the string attempting first UTF-8, then ASCII, then default.
    -  347   +  345  
          *
    -  348   +  346  
          * @param string the string to URL Decode
    -  349   +  347  
          * @return the URL Decoded string
    -  350   +  348  
          */
    -  351   +  349  
         private String urlDecode(String string) {
    -  352  4248
             final String text = string.replace("+", "%2B");
    -  353   +  350  37512
             final String text = string.replace("+", "%2B");
    +  351  
             String result;
    -  354   +  352  
             try {
    -  355  4248
                 result = URLDecoder.decode(text, "UTF-8");
    -  356  0
             } catch (UnsupportedEncodingException ex) {
    -  357   +  353  37512
                 result = URLDecoder.decode(text, "UTF-8");
    +  354  0
             } catch (UnsupportedEncodingException ex) {
    +  355  
                 try {
    -  358  0
                     result = URLDecoder.decode(text, "ASCII");
    -  359  0
                 } catch (UnsupportedEncodingException ex1) {
    -  360  0
                     result = URLDecoder.decode(text);
    -  361  0
                 }
    -  362  4248
             }
    -  363  4248
             return result;
    -  364   +  356  0
                     result = URLDecoder.decode(text, "ASCII");
    +  357  0
                 } catch (UnsupportedEncodingException ex1) {
    +  358  0
                     result = defaultUrlDecode(text);
    +  359  0
                 }
    +  360  37512
             }
    +  361  37512
             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  0
             return URLDecoder.decode(text);
    +  373   +
         }
    +  374  
     }
    - + 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 ec4123cc6..2abee8d33 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 08d416ead..edb9b9f0f 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 dccd61e91..8e9965bcf 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.reporting.EscapeTool.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.reporting.EscapeTool.html @@ -60,11 +60,11 @@  21  
     import java.net.URLEncoder;
     22   -
     import java.util.logging.Level;
    -  23   -
     import java.util.logging.Logger;
    -  24  
     import org.apache.commons.lang.StringEscapeUtils;
    +  23   +
     import org.slf4j.Logger;
    +  24   +
     import org.slf4j.LoggerFactory;
     25  
     
     26   @@ -88,7 +88,7 @@
          * The logger.
     36  
          */
    -  37  0
         private static final Logger LOGGER = Logger.getLogger(EscapeTool.class.getName());
    +  37  0
         private static final Logger LOGGER = LoggerFactory.getLogger(EscapeTool.class);
     38  
     
     39   @@ -109,8 +109,8 @@
             try {
     47  0
                 return URLEncoder.encode(text, "UTF-8");
     48  0
             } catch (UnsupportedEncodingException ex) {
    -  49  0
                 LOGGER.log(Level.WARNING, "UTF-8 is not supported?");
    -  50  0
                 LOGGER.log(Level.INFO, null, ex);
    +  49  0
                 LOGGER.warn("UTF-8 is not supported?");
    +  50  0
                 LOGGER.info("", ex);
     51  
             }
     52  0
             return "";
    @@ -158,6 +158,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 2b883c2aa..c1850a8b8 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.reporting.ReportGenerator.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.reporting.ReportGenerator.html @@ -12,7 +12,7 @@
     
    - +
    Classes in this File Line Coverage Branch Coverage Complexity
    ReportGenerator
    0%
    0/109
    0%
    0/64
    6
    ReportGenerator
    0%
    0/108
    0%
    0/64
    6
    ReportGenerator$Format
    0%
    0/5
    N/A
    6
    @@ -83,25 +83,25 @@  32  
     import java.util.List;
     33   -
     import java.util.logging.Level;
    -  34   -
     import java.util.logging.Logger;
    -  35  
     import org.apache.velocity.VelocityContext;
    -  36   +  34  
     import org.apache.velocity.app.VelocityEngine;
    -  37   +  35  
     import org.apache.velocity.context.Context;
    -  38   +  36  
     import org.apache.velocity.runtime.RuntimeConstants;
    -  39   +  37  
     import org.owasp.dependencycheck.analyzer.Analyzer;
    -  40   +  38  
     import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties;
    -  41   +  39  
     import org.owasp.dependencycheck.dependency.Dependency;
    -  42   +  40  
     import org.owasp.dependencycheck.utils.Settings;
    +  41   +
     import org.slf4j.Logger;
    +  42   +
     import org.slf4j.LoggerFactory;
     43  
     
     44   @@ -126,7 +126,7 @@
          * The logger.
     54  
          */
    -  55  0
         private static final Logger LOGGER = Logger.getLogger(ReportGenerator.class.getName());
    +  55  0
         private static final Logger LOGGER = LoggerFactory.getLogger(ReportGenerator.class);
     56  
     
     57   @@ -424,126 +424,125 @@  235  0
                     templatePath = templateName;
     236  0
                     input = new FileInputStream(f);
     237  0
                 } catch (FileNotFoundException ex) {
    -  238  0
                     final String msg = "Unable to generate the report, the report template file could not be found.";
    -  239  0
                     LOGGER.log(Level.SEVERE, msg);
    -  240  0
                     LOGGER.log(Level.FINE, null, ex);
    -  241  0
                 }
    -  242   +  238  0
                     LOGGER.error("Unable to generate the report, the report template file could not be found.");
    +  239  0
                     LOGGER.debug("", ex);
    +  240  0
                 }
    +  241  
             } else {
    -  243  0
                 templatePath = "templates/" + templateName + ".vsl";
    -  244  0
                 input = this.getClass().getClassLoader().getResourceAsStream(templatePath);
    -  245   +  242  0
                 templatePath = "templates/" + templateName + ".vsl";
    +  243  0
                 input = this.getClass().getClassLoader().getResourceAsStream(templatePath);
    +  244   +
             }
    +  245  0
             if (input == null) {
    +  246  0
                 throw new IOException("Template file doesn't exist");
    +  247  
             }
    -  246  0
             if (input == null) {
    -  247  0
                 throw new IOException("Template file doesn't exist");
     248   -
             }
    -  249  
     
    -  250  0
             final InputStreamReader reader = new InputStreamReader(input, "UTF-8");
    -  251  0
             OutputStreamWriter writer = null;
    +  249  0
             final InputStreamReader reader = new InputStreamReader(input, "UTF-8");
    +  250  0
             OutputStreamWriter writer = null;
    +  251   +
     
     252   -
     
    -  253  
             try {
    -  254  0
                 writer = new OutputStreamWriter(outputStream, "UTF-8");
    -  255   +  253  0
                 writer = new OutputStreamWriter(outputStream, "UTF-8");
    +  254  
     
    -  256  0
                 if (!engine.evaluate(context, writer, templatePath, reader)) {
    -  257  0
                     throw new Exception("Failed to convert the template into html.");
    -  258   +  255  0
                 if (!engine.evaluate(context, writer, templatePath, reader)) {
    +  256  0
                     throw new Exception("Failed to convert the template into html.");
    +  257  
                 }
    -  259  0
                 writer.flush();
    -  260   +  258  0
                 writer.flush();
    +  259  
             } finally {
    -  261  0
                 if (writer != null) {
    -  262   +  260  0
                 if (writer != null) {
    +  261  
                     try {
    -  263  0
                         writer.close();
    -  264  0
                     } catch (IOException ex) {
    -  265  0
                         LOGGER.log(Level.FINEST, null, ex);
    -  266  0
                     }
    -  267   +  262  0
                         writer.close();
    +  263  0
                     } catch (IOException ex) {
    +  264  0
                         LOGGER.trace("", ex);
    +  265  0
                     }
    +  266  
                 }
    -  268  0
                 if (outputStream != null) {
    -  269   +  267  0
                 if (outputStream != null) {
    +  268  
                     try {
    -  270  0
                         outputStream.close();
    -  271  0
                     } catch (IOException ex) {
    -  272  0
                         LOGGER.log(Level.FINEST, null, ex);
    -  273  0
                     }
    +  269  0
                         outputStream.close();
    +  270  0
                     } catch (IOException ex) {
    +  271  0
                         LOGGER.trace("", ex);
    +  272  0
                     }
    +  273   +
                 }
     274   -
                 }
    -  275  
                 try {
    -  276  0
                     reader.close();
    -  277  0
                 } catch (IOException ex) {
    -  278  0
                     LOGGER.log(Level.FINEST, null, ex);
    -  279  0
                 }
    -  280  0
             }
    -  281  0
         }
    +  275  0
                     reader.close();
    +  276  0
                 } catch (IOException ex) {
    +  277  0
                     LOGGER.trace("", ex);
    +  278  0
                 }
    +  279  0
             }
    +  280  0
         }
    +  281   +
     
     282   -
     
    -  283  
         /**
    -  284   +  283  
          * Generates a report from a given Velocity Template. The template name provided can be the name of a template
    -  285   +  284  
          * contained in the jar file, such as 'XmlReport' or 'HtmlReport', or the template name can be the path to a
    -  286   +  285  
          * template file.
    -  287   +  286  
          *
    -  288   +  287  
          * @param templateName the name of the template to load.
    -  289   +  288  
          * @param outFileName the filename and path to write the report to.
    -  290   +  289  
          * @throws IOException is thrown when the template file does not exist.
    -  291   +  290  
          * @throws Exception is thrown when an exception occurs.
    -  292   +  291  
          */
    -  293   +  292  
         protected void generateReport(String templateName, String outFileName) throws Exception {
    -  294  0
             File outFile = new File(outFileName);
    -  295  0
             if (outFile.getParentFile() == null) {
    -  296  0
                 outFile = new File(".", outFileName);
    -  297   +  293  0
             File outFile = new File(outFileName);
    +  294  0
             if (outFile.getParentFile() == null) {
    +  295  0
                 outFile = new File(".", outFileName);
    +  296  
             }
    -  298  0
             if (!outFile.getParentFile().exists()) {
    -  299  0
                 final boolean created = outFile.getParentFile().mkdirs();
    -  300  0
                 if (!created) {
    -  301  0
                     throw new Exception("Unable to create directory '" + outFile.getParentFile().getAbsolutePath() + "'.");
    +  297  0
             if (!outFile.getParentFile().exists()) {
    +  298  0
                 final boolean created = outFile.getParentFile().mkdirs();
    +  299  0
                 if (!created) {
    +  300  0
                     throw new Exception("Unable to create directory '" + outFile.getParentFile().getAbsolutePath() + "'.");
    +  301   +
                 }
     302   -
                 }
    +
             }
     303   -
             }
    -  304  
     
    -  305  0
             OutputStream outputSteam = null;
    -  306   +  304  0
             OutputStream outputSteam = null;
    +  305  
             try {
    -  307  0
                 outputSteam = new FileOutputStream(outFile);
    -  308  0
                 generateReport(templateName, outputSteam);
    -  309   +  306  0
                 outputSteam = new FileOutputStream(outFile);
    +  307  0
                 generateReport(templateName, outputSteam);
    +  308  
             } finally {
    -  310  0
                 if (outputSteam != null) {
    -  311   +  309  0
                 if (outputSteam != null) {
    +  310  
                     try {
    -  312  0
                         outputSteam.close();
    -  313  0
                     } catch (IOException ex) {
    -  314  0
                         LOGGER.log(Level.FINEST, "ignore", ex);
    -  315  0
                     }
    -  316   +  311  0
                         outputSteam.close();
    +  312  0
                     } catch (IOException ex) {
    +  313  0
                         LOGGER.trace("ignore", ex);
    +  314  0
                     }
    +  315  
                 }
    -  317   +  316  
             }
    -  318  0
         }
    -  319   +  317  0
         }
    +  318  
     }
    - + 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 b901c23ad..36debf37e 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.reporting.VelocityLoggerRedirect.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.reporting.VelocityLoggerRedirect.html @@ -12,7 +12,7 @@
     
    - +
    Classes in this File Line Coverage Branch Coverage Complexity
    VelocityLoggerRedirect
    0%
    0/15
    0%
    0/6
    3
    VelocityLoggerRedirect
    0%
    0/30
    0%
    0/12
    3.5
     
    @@ -56,13 +56,13 @@  19  
     
     20   -
     import java.util.logging.Level;
    -  21   -
     import java.util.logging.Logger;
    -  22  
     import org.apache.velocity.runtime.RuntimeServices;
    -  23   +  21  
     import org.apache.velocity.runtime.log.LogChute;
    +  22   +
     import org.slf4j.Logger;
    +  23   +
     import org.slf4j.LoggerFactory;
     24  
     
     25   @@ -70,7 +70,7 @@  26  
      * <p>
     27   -
      * DependencyCheck uses {@link java.util.logging.Logger} as a logging framework, and Apache Velocity uses a custom
    +
      * DependencyCheck uses {@link org.slf4j.Logger} as a logging framework, and Apache Velocity uses a custom
     28  
      * logging implementation that outputs to a file named velocity.log by default. This class is an implementation of a
     29   @@ -98,7 +98,7 @@
          * The Logger.
     41  
          */
    -  42  0
         private static final Logger LOGGER = Logger.getLogger(VelocityLoggerRedirect.class.getName());
    +  42  0
         private static final Logger LOGGER = LoggerFactory.getLogger(VelocityLoggerRedirect.class);
     43  
     
     44   @@ -134,92 +134,103 @@
          */
     60  
         public void log(int level, String message) {
    -  61  0
             LOGGER.log(getLevel(level), message);
    -  62  0
         }
    -  63   -
     
    -  64   -
         /**
    -  65   -
          * Given a Velocity log level, message and Throwable, this method will call the appropriate Logger level and log the
    -  66   -
          * specified values.
    -  67   -
          *
    -  68   -
          * @param level the logging level
    -  69   -
          * @param message the message to be logged
    -  70   -
          * @param t a throwable to log
    -  71   -
          */
    -  72   -
         public void log(int level, String message, Throwable t) {
    -  73  0
             LOGGER.log(getLevel(level), message, t);
    -  74  0
         }
    -  75   -
     
    -  76   -
         /**
    -  77   -
          * Will always return true. The property file will decide what level to log.
    -  78   -
          *
    -  79   -
          * @param level the logging level
    -  80   -
          * @return true
    -  81   -
          */
    -  82   -
         public boolean isLevelEnabled(int level) {
    -  83  0
             return true;
    -  84   -
         }
    -  85   -
     
    -  86   -
         /**
    -  87   -
          * Maps Velocity log levels to {@link Logger} values.
    -  88   -
          *
    -  89   -
          * @param velocityLevel the logging level
    -  90   -
          * @return the logging level
    -  91   -
          */
    -  92   -
         private Level getLevel(int velocityLevel) {
    -  93  0
             switch (velocityLevel) {
    -  94   +  61  0
             switch (level) {
    +  62  
                 case TRACE_ID:
    -  95  0
                     return Level.ALL;
    -  96   +  63  0
                     LOGGER.trace(message);
    +  64  0
                     break;
    +  65  
                 case DEBUG_ID:
    -  97  0
                     return Level.FINE;
    +  66  0
                     LOGGER.debug(message);
    +  67  0
                     break;
    +  68   +
                 case INFO_ID:
    +  69  0
                     LOGGER.info(message);
    +  70  0
                     break;
    +  71   +
                 case WARN_ID:
    +  72  0
                     LOGGER.warn(message);
    +  73  0
                     break;
    +  74   +
                 case ERROR_ID:
    +  75  0
                     LOGGER.error(message);
    +  76  0
                     break;
    +  77   +
                 default:
    +  78  0
                     LOGGER.info(message);
    +  79   +
             }
    +  80  0
         }
    +  81   +
     
    +  82   +
         /**
    +  83   +
          * Given a Velocity log level, message and Throwable, this method will call the appropriate Logger level and log the
    +  84   +
          * specified values.
    +  85   +
          *
    +  86   +
          * @param level the logging level
    +  87   +
          * @param message the message to be logged
    +  88   +
          * @param t a throwable to log
    +  89   +
          */
    +  90   +
         public void log(int level, String message, Throwable t) {
    +  91  0
             switch (level) {
    +  92   +
                 case TRACE_ID:
    +  93  0
                     LOGGER.trace(message, t);
    +  94  0
                     break;
    +  95   +
                 case DEBUG_ID:
    +  96  0
                     LOGGER.debug(message, t);
    +  97  0
                     break;
     98  
                 case INFO_ID:
    -  99  0
                     return Level.INFO;
    -  100   +  99  0
                     LOGGER.info(message, t);
    +  100  0
                     break;
    +  101  
                 case WARN_ID:
    -  101  0
                     return Level.WARNING;
    -  102   -
                 case ERROR_ID:
    -  103  0
                     return Level.SEVERE;
    +  102  0
                     LOGGER.warn(message, t);
    +  103  0
                     break;
     104   -
                 default:
    -  105  0
                     return Level.INFO;
    -  106   -
             }
    +
                 case ERROR_ID:
    +  105  0
                     LOGGER.error(message, t);
    +  106  0
                     break;
     107   +
                 default:
    +  108  0
                     LOGGER.info(message, t);
    +  109   +
             }
    +  110  0
         }
    +  111   +
     
    +  112   +
         /**
    +  113   +
          * Will always return true. The property file will decide what level to log.
    +  114   +
          *
    +  115   +
          * @param level the logging level
    +  116   +
          * @return true
    +  117   +
          */
    +  118   +
         public boolean isLevelEnabled(int level) {
    +  119  0
             return true;
    +  120  
         }
    -  108   +  121  
     }
    - + 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 0a2b23f00..8e60818a3 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  296
     public class PropertyType {
    +  28  2568
     public class PropertyType {
     29  
     
     30   @@ -100,7 +100,7 @@
          */
     42  
         public String getValue() {
    -  43  50
             return value;
    +  43  464
             return value;
     44  
         }
     45   @@ -117,15 +117,15 @@
          */
     51  
         public void setValue(String value) {
    -  52  305
             this.value = value;
    -  53  305
         }
    +  52  2640
             this.value = value;
    +  53  2640
         }
     54  
         /**
     55  
          * Whether or not the expression is a regex.
     56  
          */
    -  57  296
         private boolean regex = false;
    +  57  2568
         private boolean regex = false;
     58  
     
     59   @@ -142,7 +142,7 @@
          */
     65  
         public boolean isRegex() {
    -  66  33
             return regex;
    +  66  296
             return regex;
     67  
         }
     68   @@ -161,15 +161,15 @@
          */
     75  
         public void setRegex(boolean value) {
    -  76  289
             this.regex = value;
    -  77  289
         }
    +  76  2512
             this.regex = value;
    +  77  2512
         }
     78  
         /**
     79  
          * Indicates case sensitivity.
     80  
          */
    -  81  296
         private boolean caseSensitive = false;
    +  81  2568
         private boolean caseSensitive = false;
     82  
     
     83   @@ -186,7 +186,7 @@
          */
     89  
         public boolean isCaseSensitive() {
    -  90  23
             return caseSensitive;
    +  90  216
             return caseSensitive;
     91  
         }
     92   @@ -205,8 +205,8 @@
          */
     99  
         public void setCaseSensitive(boolean value) {
    -  100  290
             this.caseSensitive = value;
    -  101  290
         }
    +  100  2520
             this.caseSensitive = value;
    +  101  2520
         }
     102  
         //</editor-fold>
     103   @@ -225,28 +225,28 @@
          */
     110  
         public boolean matches(String text) {
    -  111  54
             if (text == null) {
    +  111  464
             if (text == null) {
     112  0
                 return false;
     113  
             }
    -  114  54
             if (this.regex) {
    +  114  464
             if (this.regex) {
     115  
                 Pattern rx;
    -  116  24
                 if (this.caseSensitive) {
    -  117  2
                     rx = Pattern.compile(this.value);
    +  116  192
                 if (this.caseSensitive) {
    +  117  16
                     rx = Pattern.compile(this.value);
     118  
                 } else {
    -  119  22
                     rx = Pattern.compile(this.value, Pattern.CASE_INSENSITIVE);
    +  119  176
                     rx = Pattern.compile(this.value, Pattern.CASE_INSENSITIVE);
     120  
                 }
    -  121  24
                 return rx.matcher(text).matches();
    +  121  192
                 return rx.matcher(text).matches();
     122  
             } else {
    -  123  30
                 if (this.caseSensitive) {
    -  124  2
                     return value.equals(text);
    +  123  272
                 if (this.caseSensitive) {
    +  124  16
                     return value.equals(text);
     125  
                 } else {
    -  126  28
                     return value.equalsIgnoreCase(text);
    +  126  256
                     return value.equalsIgnoreCase(text);
     127  
                 }
     128   @@ -296,28 +296,28 @@
         @Override
     153  
         public boolean equals(Object obj) {
    -  154  1
             if (obj == null) {
    +  154  8
             if (obj == null) {
     155  0
                 return false;
     156  
             }
    -  157  1
             if (getClass() != obj.getClass()) {
    +  157  8
             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  8
             final PropertyType other = (PropertyType) obj;
    +  161  8
             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  8
             if (this.regex != other.regex) {
     165  0
                 return false;
     166  
             }
    -  167  1
             if (this.caseSensitive != other.caseSensitive) {
    +  167  8
             if (this.caseSensitive != other.caseSensitive) {
     168  0
                 return false;
     169  
             }
    -  170  1
             return true;
    +  170  8
             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 390188477..45f497f30 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.suppression.SuppressionErrorHandler.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.suppression.SuppressionErrorHandler.html @@ -56,9 +56,9 @@  19  
     
     20   -
     import java.util.logging.Level;
    +
     import org.slf4j.Logger;
     21   -
     import java.util.logging.Logger;
    +
     import org.slf4j.LoggerFactory;
     22  
     import org.xml.sax.ErrorHandler;
     23   @@ -77,7 +77,7 @@
      * @author Jeremy Long
     30  
      */
    -  31  9
     public class SuppressionErrorHandler implements ErrorHandler {
    +  31  72
     public class SuppressionErrorHandler implements ErrorHandler {
     32  
     
     33   @@ -86,7 +86,7 @@
          * The logger.
     35  
          */
    -  36  1
         private static final Logger LOGGER = Logger.getLogger(SuppressionErrorHandler.class.getName());
    +  36  8
         private static final Logger LOGGER = LoggerFactory.getLogger(SuppressionErrorHandler.class);
     37  
     
     38   @@ -148,7 +148,7 @@
         @Override
     72  
         public void warning(SAXParseException ex) throws SAXException {
    -  73  0
             LOGGER.log(Level.FINE, null, ex);
    +  73  0
             LOGGER.debug("", ex);
     74  0
         }
     75  
     
    @@ -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 3fe1245a8..abadde457 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  72
     public class SuppressionHandler extends DefaultHandler {
     32  
     
     33   @@ -150,7 +150,7 @@
          * A list of suppression rules.
     67  
          */
    -  68  9
         private List<SuppressionRule> suppressionRules = new ArrayList<SuppressionRule>();
    +  68  72
         private List<SuppressionRule> suppressionRules = new ArrayList<SuppressionRule>();
     69  
     
     70   @@ -165,7 +165,7 @@
          */
     75  
         public List<SuppressionRule> getSuppressionRules() {
    -  76  9
             return suppressionRules;
    +  76  72
             return suppressionRules;
     77  
         }
     78   @@ -216,13 +216,13 @@
         @Override
     101  
         public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
    -  102  515
             currentAttributes = attributes;
    -  103  515
             currentText = new StringBuffer();
    -  104  515
             if (SUPPRESS.equals(qName)) {
    -  105  105
                 rule = new SuppressionRule();
    -  106  105
                 final String base = currentAttributes.getValue("base");
    -  107  105
                 if (base != null) {
    -  108  105
                     rule.setBase(Boolean.parseBoolean(base));
    +  102  4480
             currentAttributes = attributes;
    +  103  4480
             currentText = new StringBuffer();
    +  104  4480
             if (SUPPRESS.equals(qName)) {
    +  105  920
                 rule = new SuppressionRule();
    +  106  920
                 final String base = currentAttributes.getValue("base");
    +  107  920
                 if (base != null) {
    +  108  920
                     rule.setBase(Boolean.parseBoolean(base));
     109  
                 } else {
     110  0
                     rule.setBase(false);
    @@ -230,7 +230,7 @@
                 }
     112  
             }
    -  113  515
         }
    +  113  4480
         }
     114  
     
     115   @@ -253,30 +253,30 @@
         @Override
     124  
         public void endElement(String uri, String localName, String qName) throws SAXException {
    -  125  515
             if (SUPPRESS.equals(qName)) {
    -  126  105
                 suppressionRules.add(rule);
    -  127  105
                 rule = null;
    -  128  410
             } else if (FILE_PATH.equals(qName)) {
    -  129  32
                 final PropertyType pt = processPropertyType();
    -  130  32
                 rule.setFilePath(pt);
    -  131  32
             } else if (SHA1.equals(qName)) {
    -  132  4
                 rule.setSha1(currentText.toString());
    -  133  374
             } else if (GAV.equals(qName)) {
    -  134  65
                 final PropertyType pt = processPropertyType();
    -  135  65
                 rule.setGav(pt);
    -  136  65
             } else if (CPE.equals(qName)) {
    -  137  183
                 final PropertyType pt = processPropertyType();
    -  138  183
                 rule.addCpe(pt);
    -  139  183
             } else if (CWE.equals(qName)) {
    +  125  4480
             if (SUPPRESS.equals(qName)) {
    +  126  920
                 suppressionRules.add(rule);
    +  127  920
                 rule = null;
    +  128  3560
             } else if (FILE_PATH.equals(qName)) {
    +  129  256
                 final PropertyType pt = processPropertyType();
    +  130  256
                 rule.setFilePath(pt);
    +  131  256
             } else if (SHA1.equals(qName)) {
    +  132  32
                 rule.setSha1(currentText.toString());
    +  133  3272
             } else if (GAV.equals(qName)) {
    +  134  600
                 final PropertyType pt = processPropertyType();
    +  135  600
                 rule.setGav(pt);
    +  136  600
             } else if (CPE.equals(qName)) {
    +  137  1584
                 final PropertyType pt = processPropertyType();
    +  138  1584
                 rule.addCpe(pt);
    +  139  1584
             } else if (CWE.equals(qName)) {
     140  0
                 rule.addCwe(currentText.toString());
    -  141  126
             } else if (CVE.equals(qName)) {
    -  142  8
                 rule.addCve(currentText.toString());
    -  143  118
             } else if (CVSS_BELOW.equals(qName)) {
    -  144  4
                 final float cvss = Float.parseFloat(currentText.toString());
    -  145  4
                 rule.addCvssBelow(cvss);
    +  141  1088
             } else if (CVE.equals(qName)) {
    +  142  64
                 rule.addCve(currentText.toString());
    +  143  1024
             } else if (CVSS_BELOW.equals(qName)) {
    +  144  32
                 final float cvss = Float.parseFloat(currentText.toString());
    +  145  32
                 rule.addCvssBelow(cvss);
     146  
             }
    -  147  515
         }
    +  147  4480
         }
     148  
     
     149   @@ -299,8 +299,8 @@
         @Override
     158  
         public void characters(char[] ch, int start, int length) throws SAXException {
    -  159  1161
             currentText.append(ch, start, length);
    -  160  1161
         }
    +  159  10128
             currentText.append(ch, start, length);
    +  160  10128
         }
     161  
     
     162   @@ -317,28 +317,28 @@
          */
     168  
         private PropertyType processPropertyType() {
    -  169  280
             final PropertyType pt = new PropertyType();
    -  170  280
             pt.setValue(currentText.toString());
    -  171  280
             if (currentAttributes != null && currentAttributes.getLength() > 0) {
    -  172  280
                 final String regex = currentAttributes.getValue("regex");
    -  173  280
                 if (regex != null) {
    -  174  280
                     pt.setRegex(Boolean.parseBoolean(regex));
    +  169  2440
             final PropertyType pt = new PropertyType();
    +  170  2440
             pt.setValue(currentText.toString());
    +  171  2440
             if (currentAttributes != null && currentAttributes.getLength() > 0) {
    +  172  2440
                 final String regex = currentAttributes.getValue("regex");
    +  173  2440
                 if (regex != null) {
    +  174  2440
                     pt.setRegex(Boolean.parseBoolean(regex));
     175  
                 }
    -  176  280
                 final String caseSensitive = currentAttributes.getValue("caseSensitive");
    -  177  280
                 if (caseSensitive != null) {
    -  178  280
                     pt.setCaseSensitive(Boolean.parseBoolean(caseSensitive));
    +  176  2440
                 final String caseSensitive = currentAttributes.getValue("caseSensitive");
    +  177  2440
                 if (caseSensitive != null) {
    +  178  2440
                     pt.setCaseSensitive(Boolean.parseBoolean(caseSensitive));
     179  
                 }
     180  
             }
    -  181  280
             return pt;
    +  181  2440
             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 789f344f4..5406d319f 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.suppression.SuppressionParseException.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.suppression.SuppressionParseException.html @@ -113,8 +113,8 @@
          */
     50  
         public SuppressionParseException(Throwable ex) {
    -  51  1
             super(ex);
    -  52  1
         }
    +  51  8
             super(ex);
    +  52  8
         }
     53  
     
     54   @@ -131,12 +131,12 @@
          */
     60  
         public SuppressionParseException(String msg, Throwable ex) {
    -  61  1
             super(msg, ex);
    -  62  1
         }
    +  61  8
             super(msg, ex);
    +  62  8
         }
     63  
     }
    - + 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 a00e3c863..106a1082b 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.suppression.SuppressionParser.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.suppression.SuppressionParser.html @@ -72,171 +72,173 @@  27  
     import java.util.List;
     28   -
     import java.util.logging.Level;
    -  29   -
     import java.util.logging.Logger;
    -  30  
     import javax.xml.parsers.ParserConfigurationException;
    -  31   +  29  
     import javax.xml.parsers.SAXParser;
    -  32   +  30  
     import javax.xml.parsers.SAXParserFactory;
    +  31   +
     
    +  32   +
     import org.slf4j.Logger;
     33   -
     import org.xml.sax.InputSource;
    +
     import org.slf4j.LoggerFactory;
     34   -
     import org.xml.sax.SAXException;
    +
     import org.xml.sax.InputSource;
     35   -
     import org.xml.sax.XMLReader;
    +
     import org.xml.sax.SAXException;
     36   -
     
    +
     import org.xml.sax.XMLReader;
     37   -
     /**
    +
     
     38   -
      * A simple validating parser for XML Suppression Rules.
    +
     /**
     39   -
      *
    +
      * A simple validating parser for XML Suppression Rules.
     40   -
      * @author Jeremy Long
    +
      *
     41   +
      * @author Jeremy Long
    +  42  
      */
    -  42  6
     public class SuppressionParser {
    -  43   -
     
    +  43  48
     public class SuppressionParser {
     44   -
         /**
    +
     
     45   -
          * The logger.
    +
         /**
     46   +
          * The logger.
    +  47  
          */
    -  47  1
         private static final Logger LOGGER = Logger.getLogger(SuppressionParser.class.getName());
    -  48   -
         /**
    +  48  8
         private static final Logger LOGGER = LoggerFactory.getLogger(SuppressionParser.class);
     49   -
          * JAXP Schema Language. Source: http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html
    +
         /**
     50   -
          */
    +
          * JAXP Schema Language. Source: http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html
     51   -
         public static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
    +
          */
     52   -
         /**
    +
         public static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
     53   -
          * W3C XML Schema. Source: http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html
    +
         /**
     54   -
          */
    +
          * W3C XML Schema. Source: http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html
     55   -
         public static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";
    +
          */
     56   -
         /**
    +
         public static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";
     57   -
          * JAXP Schema Source. Source: http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html
    +
         /**
     58   -
          */
    +
          * JAXP Schema Source. Source: http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html
     59   -
         public static final String JAXP_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource";
    +
          */
     60   -
     
    +
         public static final String JAXP_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource";
     61   -
         /**
    +
     
     62   -
          * Parses the given xml file and returns a list of the suppression rules contained.
    -  63   -
          *
    -  64   -
          * @param file an xml file containing suppression rules
    -  65   -
          * @return a list of suppression rules
    -  66   -
          * @throws SuppressionParseException thrown if the xml file cannot be parsed
    -  67   -
          */
    -  68   -
         public List<SuppressionRule> parseSuppressionRules(File file) throws SuppressionParseException {
    -  69  4
             FileInputStream fis = null;
    -  70   -
             try {
    -  71  4
                 fis = new FileInputStream(file);
    -  72  3
                 return parseSuppressionRules(fis);
    -  73  1
             } catch (IOException ex) {
    -  74  1
                 LOGGER.log(Level.FINE, null, ex);
    -  75  1
                 throw new SuppressionParseException(ex);
    -  76   -
             } finally {
    -  77  4
                 if (fis != null) {
    -  78   -
                     try {
    -  79  3
                         fis.close();
    -  80  0
                     } catch (IOException ex) {
    -  81  0
                         LOGGER.log(Level.FINE, "Unable to close stream", ex);
    -  82  7
                     }
    -  83   -
                 }
    -  84   -
             }
    -  85   -
         }
    -  86   -
     
    -  87  
         /**
    -  88   -
          * Parses the given xml stream and returns a list of the suppression rules contained.
    -  89   +  63   +
          * Parses the given xml file and returns a list of the suppression rules contained.
    +  64  
          *
    -  90   -
          * @param inputStream an InputStream containing suppression rues
    -  91   +  65   +
          * @param file an xml file containing suppression rules
    +  66  
          * @return a list of suppression rules
    -  92   -
          * @throws SuppressionParseException if the xml cannot be parsed
    -  93   +  67   +
          * @throws SuppressionParseException thrown if the xml file cannot be parsed
    +  68  
          */
    -  94   -
         public List<SuppressionRule> parseSuppressionRules(InputStream inputStream) throws SuppressionParseException {
    -  95   +  69   +
         public List<SuppressionRule> parseSuppressionRules(File file) throws SuppressionParseException {
    +  70  32
             FileInputStream fis = null;
    +  71  
             try {
    -  96  8
                 final InputStream schemaStream = this.getClass().getClassLoader().getResourceAsStream("schema/suppression.xsd");
    -  97  8
                 final SuppressionHandler handler = new SuppressionHandler();
    -  98  8
                 final SAXParserFactory factory = SAXParserFactory.newInstance();
    -  99  8
                 factory.setNamespaceAware(true);
    -  100  8
                 factory.setValidating(true);
    -  101  8
                 final SAXParser saxParser = factory.newSAXParser();
    -  102  8
                 saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_LANGUAGE, SuppressionParser.W3C_XML_SCHEMA);
    -  103  8
                 saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_SOURCE, new InputSource(schemaStream));
    -  104  8
                 final XMLReader xmlReader = saxParser.getXMLReader();
    -  105  8
                 xmlReader.setErrorHandler(new SuppressionErrorHandler());
    -  106  8
                 xmlReader.setContentHandler(handler);
    -  107   -
     
    -  108  8
                 final Reader reader = new InputStreamReader(inputStream, "UTF-8");
    -  109  8
                 final InputSource in = new InputSource(reader);
    -  110   -
                 //in.setEncoding("UTF-8");
    -  111   -
     
    -  112  8
                 xmlReader.parse(in);
    -  113   -
     
    -  114  8
                 return handler.getSuppressionRules();
    -  115  0
             } catch (ParserConfigurationException ex) {
    -  116  0
                 LOGGER.log(Level.FINE, null, ex);
    -  117  0
                 throw new SuppressionParseException(ex);
    -  118  0
             } catch (SAXException ex) {
    -  119  0
                 LOGGER.log(Level.FINE, null, ex);
    -  120  0
                 throw new SuppressionParseException(ex);
    -  121  0
             } catch (FileNotFoundException ex) {
    -  122  0
                 LOGGER.log(Level.FINE, null, ex);
    -  123  0
                 throw new SuppressionParseException(ex);
    -  124  0
             } catch (IOException ex) {
    -  125  0
                 LOGGER.log(Level.FINE, null, ex);
    -  126  0
                 throw new SuppressionParseException(ex);
    -  127   +  72  32
                 fis = new FileInputStream(file);
    +  73  24
                 return parseSuppressionRules(fis);
    +  74  8
             } catch (IOException ex) {
    +  75  8
                 LOGGER.debug("", ex);
    +  76  8
                 throw new SuppressionParseException(ex);
    +  77   +
             } finally {
    +  78  32
                 if (fis != null) {
    +  79   +
                     try {
    +  80  24
                         fis.close();
    +  81  0
                     } catch (IOException ex) {
    +  82  0
                         LOGGER.debug("Unable to close stream", ex);
    +  83  56
                     }
    +  84   +
                 }
    +  85  
             }
    -  128   +  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  64
                 final InputStream schemaStream = this.getClass().getClassLoader().getResourceAsStream("schema/suppression.xsd");
    +  98  64
                 final SuppressionHandler handler = new SuppressionHandler();
    +  99  64
                 final SAXParserFactory factory = SAXParserFactory.newInstance();
    +  100  64
                 factory.setNamespaceAware(true);
    +  101  64
                 factory.setValidating(true);
    +  102  64
                 final SAXParser saxParser = factory.newSAXParser();
    +  103  64
                 saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_LANGUAGE, SuppressionParser.W3C_XML_SCHEMA);
    +  104  64
                 saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_SOURCE, new InputSource(schemaStream));
    +  105  64
                 final XMLReader xmlReader = saxParser.getXMLReader();
    +  106  64
                 xmlReader.setErrorHandler(new SuppressionErrorHandler());
    +  107  64
                 xmlReader.setContentHandler(handler);
    +  108   +
     
    +  109  64
                 final Reader reader = new InputStreamReader(inputStream, "UTF-8");
    +  110  64
                 final InputSource in = new InputSource(reader);
    +  111   +
                 //in.setEncoding("UTF-8");
    +  112   +
     
    +  113  64
                 xmlReader.parse(in);
    +  114   +
     
    +  115  64
                 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   +
             }
     129   +
         }
    +  130  
     }
    - + 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 449a3eb23..0314d429a 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  121
     public class SuppressionRule {
    +  31  1048
     public class SuppressionRule {
     32  
     
     33   @@ -102,7 +102,7 @@
          */
     43  
         public PropertyType getFilePath() {
    -  44  1
             return filePath;
    +  44  8
             return filePath;
     45  
         }
     46   @@ -119,8 +119,8 @@
          */
     52  
         public void setFilePath(PropertyType filePath) {
    -  53  34
             this.filePath = filePath;
    -  54  34
         }
    +  53  272
             this.filePath = filePath;
    +  54  272
         }
     55  
         /**
     56   @@ -143,7 +143,7 @@
          */
     65  
         public String getSha1() {
    -  66  1
             return sha1;
    +  66  8
             return sha1;
     67  
         }
     68   @@ -160,15 +160,15 @@
          */
     74  
         public void setSha1(String sha1) {
    -  75  6
             this.sha1 = sha1;
    -  76  6
         }
    +  75  48
             this.sha1 = sha1;
    +  76  48
         }
     77  
         /**
     78  
          * A list of CPEs to suppression
     79  
          */
    -  80  121
         private List<PropertyType> cpe = new ArrayList<PropertyType>();
    +  80  1048
         private List<PropertyType> cpe = new ArrayList<PropertyType>();
     81  
     
     82   @@ -183,7 +183,7 @@
          */
     87  
         public List<PropertyType> getCpe() {
    -  88  1
             return cpe;
    +  88  8
             return cpe;
     89  
         }
     90   @@ -200,8 +200,8 @@
          */
     96  
         public void setCpe(List<PropertyType> cpe) {
    -  97  1
             this.cpe = cpe;
    -  98  1
         }
    +  97  8
             this.cpe = cpe;
    +  98  8
         }
     99  
     
     100   @@ -216,8 +216,8 @@
          */
     105  
         public void addCpe(PropertyType cpe) {
    -  106  190
             this.cpe.add(cpe);
    -  107  190
         }
    +  106  1640
             this.cpe.add(cpe);
    +  107  1640
         }
     108  
     
     109   @@ -232,7 +232,7 @@
          */
     114  
         public boolean hasCpe() {
    -  115  19
             return !cpe.isEmpty();
    +  115  152
             return !cpe.isEmpty();
     116  
         }
     117   @@ -241,7 +241,7 @@
          * The list of cvssBelow scores.
     119  
          */
    -  120  121
         private List<Float> cvssBelow = new ArrayList<Float>();
    +  120  1048
         private List<Float> cvssBelow = new ArrayList<Float>();
     121  
     
     122   @@ -256,7 +256,7 @@
          */
     127  
         public List<Float> getCvssBelow() {
    -  128  1
             return cvssBelow;
    +  128  8
             return cvssBelow;
     129  
         }
     130   @@ -273,8 +273,8 @@
          */
     136  
         public void setCvssBelow(List<Float> cvssBelow) {
    -  137  1
             this.cvssBelow = cvssBelow;
    -  138  1
         }
    +  137  8
             this.cvssBelow = cvssBelow;
    +  138  8
         }
     139  
     
     140   @@ -289,8 +289,8 @@
          */
     145  
         public void addCvssBelow(Float cvss) {
    -  146  7
             this.cvssBelow.add(cvss);
    -  147  7
         }
    +  146  56
             this.cvssBelow.add(cvss);
    +  147  56
         }
     148  
     
     149   @@ -305,7 +305,7 @@
          */
     154  
         public boolean hasCvssBelow() {
    -  155  16
             return !cvssBelow.isEmpty();
    +  155  128
             return !cvssBelow.isEmpty();
     156  
         }
     157   @@ -314,7 +314,7 @@
          * The list of cwe entries to suppress.
     159  
          */
    -  160  121
         private List<String> cwe = new ArrayList<String>();
    +  160  1048
         private List<String> cwe = new ArrayList<String>();
     161  
     
     162   @@ -329,7 +329,7 @@
          */
     167  
         public List<String> getCwe() {
    -  168  1
             return cwe;
    +  168  8
             return cwe;
     169  
         }
     170   @@ -346,8 +346,8 @@
          */
     176  
         public void setCwe(List<String> cwe) {
    -  177  1
             this.cwe = cwe;
    -  178  1
         }
    +  177  8
             this.cwe = cwe;
    +  178  8
         }
     179  
     
     180   @@ -362,8 +362,8 @@
          */
     185  
         public void addCwe(String cwe) {
    -  186  2
             this.cwe.add(cwe);
    -  187  2
         }
    +  186  16
             this.cwe.add(cwe);
    +  187  16
         }
     188  
     
     189   @@ -378,7 +378,7 @@
          */
     194  
         public boolean hasCwe() {
    -  195  17
             return !cwe.isEmpty();
    +  195  136
             return !cwe.isEmpty();
     196  
         }
     197   @@ -387,7 +387,7 @@
          * The list of cve entries to suppress.
     199  
          */
    -  200  121
         private List<String> cve = new ArrayList<String>();
    +  200  1048
         private List<String> cve = new ArrayList<String>();
     201  
     
     202   @@ -402,7 +402,7 @@
          */
     207  
         public List<String> getCve() {
    -  208  1
             return cve;
    +  208  8
             return cve;
     209  
         }
     210   @@ -419,8 +419,8 @@
          */
     216  
         public void setCve(List<String> cve) {
    -  217  1
             this.cve = cve;
    -  218  1
         }
    +  217  8
             this.cve = cve;
    +  218  8
         }
     219  
     
     220   @@ -435,8 +435,8 @@
          */
     225  
         public void addCve(String cve) {
    -  226  11
             this.cve.add(cve);
    -  227  11
         }
    +  226  88
             this.cve.add(cve);
    +  227  88
         }
     228  
     
     229   @@ -451,7 +451,7 @@
          */
     234  
         public boolean hasCve() {
    -  235  19
             return !cve.isEmpty();
    +  235  152
             return !cve.isEmpty();
     236  
         }
     237   @@ -460,7 +460,7 @@
          * A Maven GAV to suppression.
     239  
          */
    -  240  121
         private PropertyType gav = null;
    +  240  1048
         private PropertyType gav = null;
     241  
     
     242   @@ -492,8 +492,8 @@
          */
     256  
         public void setGav(PropertyType gav) {
    -  257  66
             this.gav = gav;
    -  258  66
         }
    +  257  608
             this.gav = gav;
    +  258  608
         }
     259  
     
     260   @@ -537,7 +537,7 @@
          */
     280  
         public boolean isBase() {
    -  281  17
             return base;
    +  281  136
             return base;
     282  
         }
     283   @@ -554,8 +554,8 @@
          */
     289  
         public void setBase(boolean base) {
    -  290  107
             this.base = base;
    -  291  107
         }
    +  290  936
             this.base = base;
    +  291  936
         }
     292  
     
     293   @@ -572,71 +572,71 @@
          */
     299  
         public void process(Dependency dependency) {
    -  300  78
             if (filePath != null && !filePath.matches(dependency.getFilePath())) {
    -  301  8
                 return;
    +  300  688
             if (filePath != null && !filePath.matches(dependency.getFilePath())) {
    +  301  64
                 return;
     302  
             }
    -  303  70
             if (sha1 != null && !sha1.equalsIgnoreCase(dependency.getSha1sum())) {
    -  304  1
                 return;
    +  303  624
             if (sha1 != null && !sha1.equalsIgnoreCase(dependency.getSha1sum())) {
    +  304  8
                 return;
     305  
             }
    -  306  69
             if (gav != null) {
    -  307  53
                 final Iterator<Identifier> itr = dependency.getIdentifiers().iterator();
    -  308  53
                 boolean gavFound = false;
    -  309  109
                 while (itr.hasNext()) {
    -  310  57
                     final Identifier i = itr.next();
    -  311  57
                     if (identifierMatches("maven", this.gav, i)) {
    -  312  1
                         gavFound = true;
    -  313  1
                         break;
    +  306  616
             if (gav != null) {
    +  307  488
                 final Iterator<Identifier> itr = dependency.getIdentifiers().iterator();
    +  308  488
                 boolean gavFound = false;
    +  309  1240
                 while (itr.hasNext()) {
    +  310  760
                     final Identifier i = itr.next();
    +  311  760
                     if (identifierMatches("maven", this.gav, i)) {
    +  312  8
                         gavFound = true;
    +  313  8
                         break;
     314  
                     }
    -  315  56
                 }
    -  316  53
                 if (!gavFound) {
    -  317  52
                     return;
    +  315  752
                 }
    +  316  488
                 if (!gavFound) {
    +  317  480
                     return;
     318  
                 }
     319  
             }
     320  
     
    -  321  17
             if (this.hasCpe()) {
    -  322  12
                 final Iterator<Identifier> itr = dependency.getIdentifiers().iterator();
    -  323  30
                 while (itr.hasNext()) {
    -  324  18
                     final Identifier i = itr.next();
    -  325  18
                     for (PropertyType c : this.cpe) {
    -  326  26
                         if (identifierMatches("cpe", c, i)) {
    -  327  7
                             if (!isBase()) {
    -  328  4
                                 dependency.addSuppressedIdentifier(i);
    +  321  136
             if (this.hasCpe()) {
    +  322  96
                 final Iterator<Identifier> itr = dependency.getIdentifiers().iterator();
    +  323  272
                 while (itr.hasNext()) {
    +  324  176
                     final Identifier i = itr.next();
    +  325  176
                     for (PropertyType c : this.cpe) {
    +  326  240
                         if (identifierMatches("cpe", c, i)) {
    +  327  56
                             if (!isBase()) {
    +  328  32
                                 dependency.addSuppressedIdentifier(i);
     329  
                             }
    -  330  7
                             itr.remove();
    -  331  7
                             break;
    +  330  56
                             itr.remove();
    +  331  56
                             break;
     332  
                         }
    -  333  19
                     }
    -  334  18
                 }
    +  333  184
                     }
    +  334  176
                 }
     335  
             }
    -  336  17
             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  136
             if (hasCve() || hasCwe() || hasCvssBelow()) {
    +  337  40
                 final Iterator<Vulnerability> itr = dependency.getVulnerabilities().iterator();
    +  338  80
                 while (itr.hasNext()) {
    +  339  40
                     boolean remove = false;
    +  340  40
                     final Vulnerability v = itr.next();
    +  341  40
                     for (String entry : this.cve) {
    +  342  24
                         if (entry.equalsIgnoreCase(v.getName())) {
    +  343  8
                             remove = true;
    +  344  8
                             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  16
                     }
    +  347  40
                     if (!remove) {
    +  348  32
                         for (String entry : this.cwe) {
    +  349  8
                             if (v.getCwe() != null) {
    +  350  8
                                 final String toMatch = String.format("CWE-%s ", entry);
    +  351  8
                                 final String toTest = v.getCwe().substring(0, toMatch.length()).toUpperCase();
    +  352  8
                                 if (toTest.equals(toMatch)) {
    +  353  8
                                     remove = true;
    +  354  8
                                     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  40
                     if (!remove) {
    +  360  24
                         for (float cvss : this.cvssBelow) {
    +  361  24
                             if (v.getCvssScore() < cvss) {
    +  362  8
                                 remove = true;
    +  363  8
                                 break;
     364  
                             }
    -  365  2
                         }
    +  365  16
                         }
     366  
                     }
    -  367  5
                     if (remove) {
    -  368  3
                         if (!isBase()) {
    -  369  3
                             dependency.addSuppressedVulnerability(v);
    +  367  40
                     if (remove) {
    +  368  24
                         if (!isBase()) {
    +  369  24
                             dependency.addSuppressedVulnerability(v);
     370  
                         }
    -  371  3
                         itr.remove();
    +  371  24
                         itr.remove();
     372  
                     }
    -  373  5
                 }
    +  373  40
                 }
     374  
             }
    -  375  17
         }
    +  375  136
         }
     376  
     
     377   @@ -682,15 +682,15 @@
          */
     383  
         boolean cpeHasNoVersion(PropertyType c) {
    -  384  30
             if (c.isRegex()) {
    -  385  2
                 return false;
    +  384  272
             if (c.isRegex()) {
    +  385  16
                 return false;
     386  
             }
    -  387  28
             if (countCharacter(c.getValue(), ':') == 3) {
    -  388  22
                 return true;
    +  387  256
             if (countCharacter(c.getValue(), ':') == 3) {
    +  388  208
                 return true;
     389  
             }
    -  390  6
             return false;
    +  390  48
             return false;
     391  
         }
     392   @@ -711,14 +711,14 @@
          */
     400  
         int countCharacter(String str, char c) {
    -  401  31
             int count = 0;
    -  402  31
             int pos = str.indexOf(c) + 1;
    -  403  127
             while (pos > 0) {
    -  404  96
                 count += 1;
    -  405  96
                 pos = str.indexOf(c, pos) + 1;
    +  401  280
             int count = 0;
    +  402  280
             int pos = str.indexOf(c) + 1;
    +  403  1144
             while (pos > 0) {
    +  404  864
                 count += 1;
    +  405  864
                 pos = str.indexOf(c, pos) + 1;
     406  
             }
    -  407  31
             return count;
    +  407  280
             return count;
     408  
         }
     409   @@ -741,24 +741,24 @@
          */
     418  
         boolean identifierMatches(String identifierType, PropertyType suppressionEntry, Identifier identifier) {
    -  419  92
             if (identifierType.equals(identifier.getType())) {
    -  420  33
                 if (suppressionEntry.matches(identifier.getValue())) {
    -  421  5
                     return true;
    -  422  28
                 } else if ("cpe".equals(identifierType) && cpeHasNoVersion(suppressionEntry)) {
    -  423  21
                     if (suppressionEntry.isCaseSensitive()) {
    +  419  1072
             if (identifierType.equals(identifier.getType())) {
    +  420  296
                 if (suppressionEntry.matches(identifier.getValue())) {
    +  421  40
                     return true;
    +  422  256
                 } else if ("cpe".equals(identifierType) && cpeHasNoVersion(suppressionEntry)) {
    +  423  200
                     if (suppressionEntry.isCaseSensitive()) {
     424  0
                         return identifier.getValue().startsWith(suppressionEntry.getValue());
     425  
                     } else {
    -  426  21
                         final String id = identifier.getValue().toLowerCase();
    -  427  21
                         final String check = suppressionEntry.getValue().toLowerCase();
    -  428  21
                         return id.startsWith(check);
    +  426  200
                         final String id = identifier.getValue().toLowerCase();
    +  427  200
                         final String check = suppressionEntry.getValue().toLowerCase();
    +  428  200
                         return id.startsWith(check);
     429  
                     }
     430  
                 }
     431  
             }
    -  432  66
             return false;
    +  432  832
             return false;
     433  
         }
     434   @@ -831,6 +831,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 d3bad61bc..ba38cecd2 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.DBUtils.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.DBUtils.html @@ -64,11 +64,11 @@  23  
     import java.sql.Statement;
     24   -
     import java.util.logging.Level;
    -  25   -
     import java.util.logging.Logger;
    -  26  
     import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
    +  25   +
     import org.slf4j.Logger;
    +  26   +
     import org.slf4j.LoggerFactory;
     27  
     
     28   @@ -89,7 +89,7 @@
          * The logger.
     36  
          */
    -  37  1
         private static final Logger LOGGER = Logger.getLogger(DBUtils.class.getName());
    +  37  8
         private static final Logger LOGGER = LoggerFactory.getLogger(DBUtils.class);
     38  
     
     39   @@ -151,16 +151,16 @@
          */
     74  
         public static void closeStatement(Statement statement) {
    -  75  34
             if (statement != null) {
    +  75  312
             if (statement != null) {
     76  
                 try {
    -  77  34
                     statement.close();
    +  77  312
                     statement.close();
     78  0
                 } catch (SQLException ex) {
    -  79  0
                     LOGGER.log(Level.FINEST, statement.toString(), ex);
    -  80  34
                 }
    +  79  0
                     LOGGER.trace(statement.toString(), ex);
    +  80  312
                 }
     81  
             }
    -  82  34
         }
    +  82  312
         }
     83  
     
     84   @@ -175,20 +175,20 @@
          */
     89  
         public static void closeResultSet(ResultSet rs) {
    -  90  36
             if (rs != null) {
    +  90  336
             if (rs != null) {
     91  
                 try {
    -  92  36
                     rs.close();
    +  92  336
                     rs.close();
     93  0
                 } catch (SQLException ex) {
    -  94  0
                     LOGGER.log(Level.FINEST, rs.toString(), ex);
    -  95  36
                 }
    +  94  0
                     LOGGER.trace(rs.toString(), ex);
    +  95  336
                 }
     96  
             }
    -  97  36
         }
    +  97  336
         }
     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 3bf4ab930..cdfa0b8e2 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.DateUtil.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.DateUtil.html @@ -99,14 +99,14 @@
          */
     42  
         public static boolean withinDateRange(long date, long compareTo, int range) {
    -  43  9
             final double differenceInDays = (compareTo - date) / 1000.0 / 60.0 / 60.0 / 24.0;
    -  44  9
             return differenceInDays < range;
    +  43  47
             final double differenceInDays = (compareTo - date) / 1000.0 / 60.0 / 60.0 / 24.0;
    +  44  47
             return differenceInDays < range;
     45  
         }
     46  
     }
    - + 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 49dce5904..244525ea1 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.DependencyVersion.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.DependencyVersion.html @@ -12,7 +12,7 @@
     
    - +
    Classes in this File Line Coverage Branch Coverage Complexity
    DependencyVersion
    90%
    80/88
    76%
    49/64
    5.273
    DependencyVersion
    90%
    80/88
    78%
    50/64
    5.273
     
    @@ -95,7 +95,7 @@
      * @author Jeremy Long
     39  
      */
    -  40  14
     public class DependencyVersion implements Iterable, Comparable<DependencyVersion> {
    +  40  112
     public class DependencyVersion implements Iterable, Comparable<DependencyVersion> {
     41  
     
     42   @@ -104,8 +104,8 @@
          * Constructor for a empty DependencyVersion.
     44  
          */
    -  45  4
         public DependencyVersion() {
    -  46  4
         }
    +  45  32
         public DependencyVersion() {
    +  46  32
         }
     47  
     
     48   @@ -122,9 +122,9 @@
          * @param version the well formatted version number to parse
     54  
          */
    -  55  787
         public DependencyVersion(String version) {
    -  56  787
             parseVersion(version);
    -  57  787
         }
    +  55  8172
         public DependencyVersion(String version) {
    +  56  8172
             parseVersion(version);
    +  57  8172
         }
     58  
     
     59   @@ -141,21 +141,21 @@
          */
     65  
         public final void parseVersion(String version) {
    -  66  789
             versionParts = new ArrayList<String>();
    -  67  789
             if (version != null) {
    -  68  789
                 final Pattern rx = Pattern.compile("(\\d+[a-z]{1,3}$|[a-z]+\\d+|\\d+|(release|beta|alpha)$)");
    -  69  789
                 final Matcher matcher = rx.matcher(version.toLowerCase());
    -  70  3338
                 while (matcher.find()) {
    -  71  2549
                     versionParts.add(matcher.group());
    +  66  8188
             versionParts = new ArrayList<String>();
    +  67  8188
             if (version != null) {
    +  68  8183
                 final Pattern rx = Pattern.compile("(\\d+[a-z]{1,3}$|[a-z]+\\d+|\\d+|(release|beta|alpha)$)");
    +  69  8183
                 final Matcher matcher = rx.matcher(version.toLowerCase());
    +  70  34131
                 while (matcher.find()) {
    +  71  25948
                     versionParts.add(matcher.group());
     72  
                 }
    -  73  789
                 if (versionParts.isEmpty()) {
    -  74  5
                     versionParts.add(version);
    +  73  8183
                 if (versionParts.isEmpty()) {
    +  74  43
                     versionParts.add(version);
     75  
                 }
     76  
             }
    -  77  789
         }
    +  77  8188
         }
     78  
         /**
     79   @@ -178,7 +178,7 @@
          */
     88  
         public List<String> getVersionParts() {
    -  89  1341
             return versionParts;
    +  89  14418
             return versionParts;
     90  
         }
     91   @@ -195,8 +195,8 @@
          */
     97  
         public void setVersionParts(List<String> versionParts) {
    -  98  3
             this.versionParts = versionParts;
    -  99  3
         }
    +  98  24
             this.versionParts = versionParts;
    +  99  24
         }
     100  
     
     101   @@ -211,7 +211,7 @@
          */
     106  
         public Iterator iterator() {
    -  107  1
             return versionParts.iterator();
    +  107  8
             return versionParts.iterator();
     108  
         }
     109   @@ -230,7 +230,7 @@
         @Override
     116  
         public String toString() {
    -  117  257
             return StringUtils.join(versionParts.toArray(), ".");
    +  117  2526
             return StringUtils.join(versionParts.toArray(), ".");
     118  
         }
     119   @@ -251,30 +251,30 @@
         @Override
     127  
         public boolean equals(Object obj) {
    -  128  480
             if (obj == null) {
    +  128  5280
             if (obj == null) {
     129  0
                 return false;
     130  
             }
    -  131  480
             if (getClass() != obj.getClass()) {
    +  131  5280
             if (getClass() != obj.getClass()) {
     132  0
                 return false;
     133  
             }
    -  134  480
             final DependencyVersion other = (DependencyVersion) obj;
    -  135  480
             final int max = (this.versionParts.size() < other.versionParts.size())
    +  134  5280
             final DependencyVersion other = (DependencyVersion) obj;
    +  135  5280
             final int max = (this.versionParts.size() < other.versionParts.size())
     136  
                     ? this.versionParts.size() : other.versionParts.size();
     137  
             //TODO steal better version of code from compareTo
    -  138  1133
             for (int i = 0; i < max; i++) {
    -  139  1002
                 final String thisPart = this.versionParts.get(i);
    -  140  1002
                 final String otherPart = other.versionParts.get(i);
    -  141  1002
                 if (!thisPart.equals(otherPart)) {
    -  142  349
                     return false;
    +  138  11696
             for (int i = 0; i < max; i++) {
    +  139  10648
                 final String thisPart = this.versionParts.get(i);
    +  140  10648
                 final String otherPart = other.versionParts.get(i);
    +  141  10648
                 if (!thisPart.equals(otherPart)) {
    +  142  4232
                     return false;
     143  
                 }
     144  
             }
    -  145  131
             if (this.versionParts.size() > max) {
    +  145  1048
             if (this.versionParts.size() > max) {
     146  0
                 for (int i = max; i < this.versionParts.size(); i++) {
     147  0
                     if (!"0".equals(this.versionParts.get(i))) {
     148  0
                         return false;
    @@ -286,10 +286,10 @@
             }
     152  
     
    -  153  131
             if (other.versionParts.size() > max) {
    -  154  107
                 for (int i = max; i < other.versionParts.size(); i++) {
    -  155  107
                     if (!"0".equals(other.versionParts.get(i))) {
    -  156  107
                         return false;
    +  153  1048
             if (other.versionParts.size() > max) {
    +  154  856
                 for (int i = max; i < other.versionParts.size(); i++) {
    +  155  856
                     if (!"0".equals(other.versionParts.get(i))) {
    +  156  856
                         return false;
     157  
                     }
     158   @@ -308,7 +308,7 @@
              *  }
     165  
              */
    -  166  24
             return true;
    +  166  192
             return true;
     167  
         }
     168   @@ -327,9 +327,9 @@
         @Override
     175  
         public int hashCode() {
    -  176  1
             int hash = 5;
    -  177  1
             hash = 71 * hash + (this.versionParts != null ? this.versionParts.hashCode() : 0);
    -  178  1
             return hash;
    +  176  8
             int hash = 5;
    +  177  8
             hash = 71 * hash + (this.versionParts != null ? this.versionParts.hashCode() : 0);
    +  178  8
             return hash;
     179  
         }
     180   @@ -350,41 +350,41 @@
          */
     188  
         public boolean matchesAtLeastThreeLevels(DependencyVersion version) {
    -  189  304
             if (version == null) {
    +  189  3392
             if (version == null) {
     190  0
                 return false;
     191  
             }
    -  192  304
             if (Math.abs(this.versionParts.size() - version.versionParts.size()) >= 3) {
    -  193  1
                 return false;
    +  192  3392
             if (Math.abs(this.versionParts.size() - version.versionParts.size()) >= 3) {
    +  193  8
                 return false;
     194  
             }
     195  
     
    -  196  303
             final int max = (this.versionParts.size() < version.versionParts.size())
    +  196  3384
             final int max = (this.versionParts.size() < version.versionParts.size())
     197  
                     ? this.versionParts.size() : version.versionParts.size();
     198  
     
    -  199  303
             boolean ret = true;
    -  200  652
             for (int i = 0; i < max; i++) {
    -  201  586
                 final String thisVersion = this.versionParts.get(i);
    -  202  586
                 final String otherVersion = version.getVersionParts().get(i);
    -  203  586
                 if (i >= 3) {
    -  204  2
                     if (thisVersion.compareToIgnoreCase(otherVersion) >= 0) {
    -  205  1
                         ret = false;
    -  206  1
                         break;
    +  199  3384
             boolean ret = true;
    +  200  6976
             for (int i = 0; i < max; i++) {
    +  201  6448
                 final String thisVersion = this.versionParts.get(i);
    +  202  6448
                 final String otherVersion = version.getVersionParts().get(i);
    +  203  6448
                 if (i >= 3) {
    +  204  16
                     if (thisVersion.compareToIgnoreCase(otherVersion) >= 0) {
    +  205  8
                         ret = false;
    +  206  8
                         break;
     207  
                     }
    -  208  584
                 } else if (!thisVersion.equals(otherVersion)) {
    -  209  236
                     ret = false;
    -  210  236
                     break;
    +  208  6432
                 } else if (!thisVersion.equals(otherVersion)) {
    +  209  2848
                     ret = false;
    +  210  2848
                     break;
     211  
                 }
     212  
             }
     213  
     
    -  214  303
             return ret;
    +  214  3384
             return ret;
     215  
         }
     216   @@ -393,50 +393,50 @@
         @Override
     218  
         public int compareTo(DependencyVersion version) {
    -  219  30
             if (version == null) {
    +  219  215
             if (version == null) {
     220  0
                 return 1;
     221  
             }
    -  222  30
             final List<String> left = this.getVersionParts();
    -  223  30
             final List<String> right = version.getVersionParts();
    -  224  30
             final int max = left.size() < right.size() ? left.size() : right.size();
    +  222  215
             final List<String> left = this.getVersionParts();
    +  223  215
             final List<String> right = version.getVersionParts();
    +  224  215
             final int max = left.size() < right.size() ? left.size() : right.size();
     225  
     
    -  226  79
             for (int i = 0; i < max; i++) {
    -  227  69
                 final String lStr = left.get(i);
    -  228  69
                 final String rStr = right.get(i);
    -  229  69
                 if (lStr.equals(rStr)) {
    -  230  49
                     continue;
    +  226  557
             for (int i = 0; i < max; i++) {
    +  227  472
                 final String lStr = left.get(i);
    +  228  472
                 final String rStr = right.get(i);
    +  229  472
                 if (lStr.equals(rStr)) {
    +  230  342
                     continue;
     231  
                 }
     232  
                 try {
    -  233  20
                     final int l = Integer.parseInt(lStr);
    -  234  13
                     final int r = Integer.parseInt(rStr);
    -  235  12
                     if (l < r) {
    -  236  9
                         return -1;
    -  237  3
                     } else if (l > r) {
    -  238  3
                         return 1;
    +  233  130
                     final int l = Integer.parseInt(lStr);
    +  234  74
                     final int r = Integer.parseInt(rStr);
    +  235  71
                     if (l < r) {
    +  236  52
                         return -1;
    +  237  19
                     } else if (l > r) {
    +  238  19
                         return 1;
     239  
                     }
    -  240  8
                 } catch (NumberFormatException ex) {
    -  241  8
                     final int comp = left.get(i).compareTo(right.get(i));
    -  242  8
                     if (comp < 0) {
    -  243  6
                         return -1;
    -  244  2
                     } else if (comp > 0) {
    -  245  2
                         return 1;
    +  240  59
                 } catch (NumberFormatException ex) {
    +  241  59
                     final int comp = left.get(i).compareTo(right.get(i));
    +  242  59
                     if (comp < 0) {
    +  243  48
                         return -1;
    +  244  11
                     } else if (comp > 0) {
    +  245  11
                         return 1;
     246  
                     }
     247  0
                 }
     248  
             }
    -  249  10
             if (left.size() < right.size()) {
    -  250  3
                 return -1;
    -  251  7
             } else if (left.size() > right.size()) {
    -  252  3
                 return 1;
    +  249  85
             if (left.size() < right.size()) {
    +  250  24
                 return -1;
    +  251  61
             } else if (left.size() > right.size()) {
    +  252  29
                 return 1;
     253  
             } else {
    -  254  4
                 return 0;
    +  254  32
                 return 0;
     255  
             }
     256   @@ -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 ffb8c50d6..5ab98f91d 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  8
         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  8
         private static final Pattern RX_SINGLE_VERSION = Pattern.compile("\\d+(\\.?([_-](release|beta|alpha)|[a-zA-Z_-]{1,3}\\d{1,8}))?");
     42  
     
     43   @@ -131,60 +131,60 @@
          */
     59  
         public static DependencyVersion parseVersion(String text) {
    -  60  738
             if (text == null) {
    +  60  7832
             if (text == null) {
     61  0
                 return null;
     62  
             }
     63  
             //'-' is a special case used within the CVE entries, just include it as the version.
    -  64  738
             if ("-".equals(text)) {
    -  65  1
                 final DependencyVersion dv = new DependencyVersion();
    -  66  1
                 final List<String> list = new ArrayList<String>();
    -  67  1
                 list.add(text);
    -  68  1
                 dv.setVersionParts(list);
    -  69  1
                 return dv;
    +  64  7832
             if ("-".equals(text)) {
    +  65  8
                 final DependencyVersion dv = new DependencyVersion();
    +  66  8
                 final List<String> list = new ArrayList<String>();
    +  67  8
                 list.add(text);
    +  68  8
                 dv.setVersionParts(list);
    +  69  8
                 return dv;
     70  
             }
    -  71  737
             String version = null;
    -  72  737
             Matcher matcher = RX_VERSION.matcher(text);
    -  73  737
             if (matcher.find()) {
    -  74  733
                 version = matcher.group();
    +  71  7824
             String version = null;
    +  72  7824
             Matcher matcher = RX_VERSION.matcher(text);
    +  73  7824
             if (matcher.find()) {
    +  74  7792
                 version = matcher.group();
     75  
             }
     76  
             //throw away the results if there are two things that look like version numbers
    -  77  737
             if (matcher.find()) {
    -  78  2
                 return null;
    +  77  7824
             if (matcher.find()) {
    +  78  16
                 return null;
     79  
             }
    -  80  735
             if (version == null) {
    -  81  4
                 matcher = RX_SINGLE_VERSION.matcher(text);
    -  82  4
                 if (matcher.find()) {
    -  83  2
                     version = matcher.group();
    +  80  7808
             if (version == null) {
    +  81  32
                 matcher = RX_SINGLE_VERSION.matcher(text);
    +  82  32
                 if (matcher.find()) {
    +  83  16
                     version = matcher.group();
     84  
                 } else {
    -  85  2
                     return null;
    +  85  16
                     return null;
     86  
                 }
     87  
                 //throw away the results if there are two things that look like version numbers
    -  88  2
                 if (matcher.find()) {
    -  89  1
                     return null;
    +  88  16
                 if (matcher.find()) {
    +  89  8
                     return null;
     90  
                 }
     91  
             }
    -  92  732
             if (version != null && version.endsWith("-py2") && version.length() > 4) {
    -  93  1
                 version = version.substring(0, version.length() - 4);
    +  92  7784
             if (version != null && version.endsWith("-py2") && version.length() > 4) {
    +  93  8
                 version = version.substring(0, version.length() - 4);
     94  
             }
    -  95  732
             return new DependencyVersion(version);
    +  95  7784
             return new DependencyVersion(version);
     96  
         }
     97  
     }
    - + 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 afafda8c9..39b2f70fd 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.ExtractionUtil.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.ExtractionUtil.html @@ -12,7 +12,7 @@
     
    - +
    Classes in this File Line Coverage Branch Coverage Complexity
    ExtractionUtil
    34%
    42/122
    31%
    12/38
    6
    ExtractionUtil
    34%
    41/119
    31%
    12/38
    6
     
    @@ -56,467 +56,456 @@  19  
     
     20   -
     import static org.owasp.dependencycheck.utils.FileUtils.getFileExtension;
    -  21   -
     
    -  22  
     import java.io.BufferedInputStream;
    -  23   +  21  
     import java.io.BufferedOutputStream;
    -  24   +  22  
     import java.io.Closeable;
    -  25   +  23  
     import java.io.File;
    -  26   +  24  
     import java.io.FileInputStream;
    -  27   +  25  
     import java.io.FileNotFoundException;
    -  28   +  26  
     import java.io.FileOutputStream;
    -  29   +  27  
     import java.io.FilenameFilter;
    -  30   +  28  
     import java.io.IOException;
    -  31   +  29  
     import java.io.InputStream;
    -  32   -
     import java.util.logging.Level;
    -  33   -
     import java.util.logging.Logger;
    -  34   +  30  
     import java.util.zip.ZipEntry;
    -  35   +  31  
     import java.util.zip.ZipInputStream;
    -  36   +  32  
     
    -  37   +  33  
     import org.apache.commons.compress.archivers.ArchiveEntry;
    -  38   +  34  
     import org.apache.commons.compress.archivers.ArchiveInputStream;
    -  39   +  35  
     import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
    -  40   +  36  
     import org.owasp.dependencycheck.Engine;
    -  41   +  37  
     import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
    -  42   +  38  
     import org.owasp.dependencycheck.analyzer.exception.ArchiveExtractionException;
    -  43   +  39   +
     import org.slf4j.Logger;
    +  40   +
     import org.slf4j.LoggerFactory;
    +  41  
     
    -  44   +  42  
     /**
    -  45   +  43  
      * Set of utilities to extract files from archives.
    -  46   +  44  
      *
    -  47   +  45  
      * @author Jeremy Long
    -  48   +  46  
      */
    -  49   +  47  
     public final class ExtractionUtil {
    +  48   +
     
    +  49   +
         /**
     50   -
     
    -  51   -
         /**
    -  52  
          * The logger.
    +  51   +
          */
    +  52  8
         private static final Logger LOGGER = LoggerFactory.getLogger(ExtractionUtil.class);
     53   -
          */
    -  54  1
         private static final Logger LOGGER = Logger.getLogger(ExtractionUtil.class.getName());
    -  55  
         /**
    -  56   +  54  
          * The buffer size to use when extracting files from the archive.
    -  57   +  55  
          */
    -  58   +  56  
         private static final int BUFFER_SIZE = 4096;
    +  57   +
     
    +  58   +
         /**
     59   -
     
    -  60   -
         /**
    -  61  
          * Private constructor for a utility class.
    -  62   +  60  
          */
    -  63  0
         private ExtractionUtil() {
    -  64  0
         }
    +  61  0
         private ExtractionUtil() {
    +  62  0
         }
    +  63   +
     
    +  64   +
         /**
     65   -
     
    +
          * Extracts the contents of an archive into the specified directory.
     66   -
         /**
    +
          *
     67   -
          * Extracts the contents of an archive into the specified directory.
    +
          * @param archive an archive file such as a WAR or EAR
     68   -
          *
    +
          * @param extractTo a directory to extract the contents to
     69   -
          * @param archive an archive file such as a WAR or EAR
    -  70   -
          * @param extractTo a directory to extract the contents to
    -  71  
          * @throws ExtractionException thrown if an exception occurs while extracting the files
    -  72   +  70  
          */
    -  73   +  71  
         public static void extractFiles(File archive, File extractTo) throws ExtractionException {
    -  74  0
             extractFiles(archive, extractTo, null);
    -  75  0
         }
    +  72  0
             extractFiles(archive, extractTo, null);
    +  73  0
         }
    +  74   +
     
    +  75   +
         /**
     76   -
     
    -  77   -
         /**
    -  78  
          * Extracts the contents of an archive into the specified directory. The files are only extracted if they are supported by the
    -  79   +  77  
          * analyzers loaded into the specified engine. If the engine is specified as null then all files are extracted.
    +  78   +
          *
    +  79   +
          * @param archive an archive file such as a WAR or EAR
     80   -
          *
    -  81   -
          * @param archive an archive file such as a WAR or EAR
    -  82  
          * @param extractTo a directory to extract the contents to
    -  83   +  81  
          * @param engine the scanning engine
    -  84   +  82  
          * @throws ExtractionException thrown if there is an error extracting the files
    -  85   +  83  
          */
    -  86   +  84  
         public static void extractFiles(File archive, File extractTo, Engine engine) throws ExtractionException {
    -  87  0
             if (archive == null || extractTo == null) {
    -  88  0
                 return;
    -  89   +  85  0
             if (archive == null || extractTo == null) {
    +  86  0
                 return;
    +  87  
             }
    -  90   +  88  
     
    -  91  0
             FileInputStream fis = null;
    -  92  0
             ZipInputStream zis = null;
    -  93   +  89  0
             FileInputStream fis = null;
    +  90  0
             ZipInputStream zis = null;
    +  91  
     
    -  94   +  92  
             try {
    -  95  0
                 fis = new FileInputStream(archive);
    -  96  0
             } catch (FileNotFoundException ex) {
    -  97  0
                 LOGGER.log(Level.FINE, null, ex);
    -  98  0
                 throw new ExtractionException("Archive file was not found.", ex);
    -  99  0
             }
    -  100  0
             zis = new ZipInputStream(new BufferedInputStream(fis));
    -  101   +  93  0
                 fis = new FileInputStream(archive);
    +  94  0
             } catch (FileNotFoundException ex) {
    +  95  0
                 LOGGER.debug("", ex);
    +  96  0
                 throw new ExtractionException("Archive file was not found.", ex);
    +  97  0
             }
    +  98  0
             zis = new ZipInputStream(new BufferedInputStream(fis));
    +  99  
             ZipEntry entry;
    -  102   +  100  
             try {
    -  103  0
                 while ((entry = zis.getNextEntry()) != null) {
    -  104  0
                     if (entry.isDirectory()) {
    -  105  0
                         final File d = new File(extractTo, entry.getName());
    -  106  0
                         if (!d.exists() && !d.mkdirs()) {
    -  107  0
                             final String msg = String.format("Unable to create '%s'.", d.getAbsolutePath());
    -  108  0
                             throw new ExtractionException(msg);
    -  109   +  101  0
                 while ((entry = zis.getNextEntry()) != null) {
    +  102  0
                     if (entry.isDirectory()) {
    +  103  0
                         final File d = new File(extractTo, entry.getName());
    +  104  0
                         if (!d.exists() && !d.mkdirs()) {
    +  105  0
                             final String msg = String.format("Unable to create '%s'.", d.getAbsolutePath());
    +  106  0
                             throw new ExtractionException(msg);
    +  107  
                         }
    -  110  0
                     } else {
    -  111  0
                         final File file = new File(extractTo, entry.getName());
    -  112  0
                         final String ext = getFileExtension(file.getName());
    -  113  0
                         if (engine == null || engine.supportsExtension(ext)) {
    -  114  0
                             BufferedOutputStream bos = null;
    -  115   +  108  0
                     } else {
    +  109  0
                         final File file = new File(extractTo, entry.getName());
    +  110  0
                         if (engine == null || engine.accept(file)) {
    +  111  0
                             BufferedOutputStream bos = null;
    +  112  
                             FileOutputStream fos;
    -  116   +  113  
                             try {
    -  117  0
                                 fos = new FileOutputStream(file);
    -  118  0
                                 bos = new BufferedOutputStream(fos, BUFFER_SIZE);
    -  119  0
                                 transferUsingBuffer(zis, bos);
    -  120  0
                             } catch (FileNotFoundException ex) {
    -  121  0
                                 LOGGER.log(Level.FINE, null, ex);
    -  122  0
                                 final String msg = String.format("Unable to find file '%s'.", file.getName());
    -  123  0
                                 throw new ExtractionException(msg, ex);
    -  124  0
                             } catch (IOException ex) {
    -  125  0
                                 LOGGER.log(Level.FINE, null, ex);
    -  126  0
                                 final String msg = String.format("IO Exception while parsing file '%s'.", file.getName());
    -  127  0
                                 throw new ExtractionException(msg, ex);
    -  128   +  114  0
                                 fos = new FileOutputStream(file);
    +  115  0
                                 bos = new BufferedOutputStream(fos, BUFFER_SIZE);
    +  116  0
                                 transferUsingBuffer(zis, bos);
    +  117  0
                             } catch (FileNotFoundException ex) {
    +  118  0
                                 LOGGER.debug("", ex);
    +  119  0
                                 final String msg = String.format("Unable to find file '%s'.", file.getName());
    +  120  0
                                 throw new ExtractionException(msg, ex);
    +  121  0
                             } catch (IOException ex) {
    +  122  0
                                 LOGGER.debug("", ex);
    +  123  0
                                 final String msg = String.format("IO Exception while parsing file '%s'.", file.getName());
    +  124  0
                                 throw new ExtractionException(msg, ex);
    +  125  
                             } finally {
    -  129  0
                                 closeStream(bos);
    -  130  0
                             }
    -  131   +  126  0
                                 closeStream(bos);
    +  127  0
                             }
    +  128  
                         }
    -  132  0
                     }
    -  133   +  129  0
                     }
    +  130  
                 }
    -  134  0
             } catch (IOException ex) {
    -  135  0
                 final String msg = String.format("Exception reading archive '%s'.", archive.getName());
    -  136  0
                 LOGGER.log(Level.FINE, msg, ex);
    -  137  0
                 throw new ExtractionException(msg, ex);
    -  138   +  131  0
             } catch (IOException ex) {
    +  132  0
                 final String msg = String.format("Exception reading archive '%s'.", archive.getName());
    +  133  0
                 LOGGER.debug("", ex);
    +  134  0
                 throw new ExtractionException(msg, ex);
    +  135  
             } finally {
    -  139  0
                 closeStream(zis);
    -  140  0
             }
    -  141  0
         }
    -  142   +  136  0
                 closeStream(zis);
    +  137  0
             }
    +  138  0
         }
    +  139  
     
    -  143   +  140  
         /**
    -  144   +  141  
          * Extracts the contents of an archive into the specified directory.
    -  145   +  142  
          *
    -  146   +  143  
          * @param archive an archive file such as a WAR or EAR
    -  147   +  144  
          * @param destination a directory to extract the contents to
    -  148   +  145  
          * @param filter determines which files get extracted
    -  149   +  146  
          * @throws ExtractionException thrown if the archive is not found
    -  150   +  147  
          */
    -  151   +  148  
         public static void extractFilesUsingFilter(File archive, File destination,
    -  152   +  149  
                 FilenameFilter filter) throws ExtractionException {
    -  153  3
             if (archive == null || destination == null) {
    -  154  0
                 return;
    +  150  24
             if (archive == null || destination == null) {
    +  151  0
                 return;
    +  152   +
             }
    +  153   +
     
    +  154  24
             FileInputStream fis = null;
     155   -
             }
    -  156   -
     
    -  157  3
             FileInputStream fis = null;
    -  158  
             try {
    -  159  3
                 fis = new FileInputStream(archive);
    -  160  0
             } catch (FileNotFoundException ex) {
    -  161  0
                 LOGGER.log(Level.FINE, null, ex);
    -  162  0
                 throw new ExtractionException("Archive file was not found.", ex);
    -  163  3
             }
    -  164   +  156  24
                 fis = new FileInputStream(archive);
    +  157  0
             } catch (FileNotFoundException ex) {
    +  158  0
                 LOGGER.debug("", ex);
    +  159  0
                 throw new ExtractionException("Archive file was not found.", ex);
    +  160  24
             }
    +  161  
             try {
    -  165  3
                 extractArchive(new ZipArchiveInputStream(new BufferedInputStream(
    -  166   +  162  24
                 extractArchive(new ZipArchiveInputStream(new BufferedInputStream(
    +  163  
                         fis)), destination, filter);
    -  167  0
             } catch (ArchiveExtractionException ex) {
    -  168  0
                 final String msg = String.format(
    -  169   -
                         "Exception extracting archive '%s'.", archive.getName());
    -  170  0
                 LOGGER.log(Level.WARNING, msg);
    -  171  0
                 LOGGER.log(Level.FINE, null, ex);
    -  172   +  164  0
             } catch (ArchiveExtractionException ex) {
    +  165  0
                 LOGGER.warn("Exception extracting archive '{}'.", archive.getName());
    +  166  0
                 LOGGER.debug("", ex);
    +  167  
             } finally {
    -  173  0
                 try {
    -  174  3
                     fis.close();
    -  175  0
                 } catch (IOException ex) {
    -  176  0
                     LOGGER.log(Level.FINE, null, ex);
    -  177  3
                 }
    -  178  0
             }
    -  179  3
         }
    -  180   +  168  0
                 try {
    +  169  24
                     fis.close();
    +  170  0
                 } catch (IOException ex) {
    +  171  0
                     LOGGER.debug("", ex);
    +  172  24
                 }
    +  173  0
             }
    +  174  24
         }
    +  175  
     
    -  181   +  176  
         /**
    -  182   +  177  
          * Extracts files from an archive.
    -  183   +  178  
          *
    -  184   +  179  
          * @param input the archive to extract files from
    -  185   +  180  
          * @param destination the location to write the files too
    -  186   +  181  
          * @param filter determines which files get extracted
    -  187   +  182  
          * @throws ArchiveExtractionException thrown if there is an exception extracting files from the archive
    -  188   +  183  
          */
    -  189   +  184  
         private static void extractArchive(ArchiveInputStream input,
    -  190   +  185  
                 File destination, FilenameFilter filter)
    -  191   +  186  
                 throws ArchiveExtractionException {
    -  192   +  187  
             ArchiveEntry entry;
    -  193   +  188  
             try {
    -  194  36
                 while ((entry = input.getNextEntry()) != null) {
    -  195  33
                     if (entry.isDirectory()) {
    -  196  0
                         final File dir = new File(destination, entry.getName());
    -  197  0
                         if (!dir.exists()) {
    -  198  0
                             if (!dir.mkdirs()) {
    -  199  0
                                 final String msg = String.format(
    -  200   +  189  288
                 while ((entry = input.getNextEntry()) != null) {
    +  190  264
                     if (entry.isDirectory()) {
    +  191  0
                         final File dir = new File(destination, entry.getName());
    +  192  0
                         if (!dir.exists()) {
    +  193  0
                             if (!dir.mkdirs()) {
    +  194  0
                                 final String msg = String.format(
    +  195  
                                         "Unable to create directory '%s'.",
    -  201   +  196  
                                         dir.getAbsolutePath());
    -  202  0
                                 throw new AnalysisException(msg);
    -  203   +  197  0
                                 throw new AnalysisException(msg);
    +  198  
                             }
    -  204   +  199  
                         }
    -  205  0
                     } else {
    -  206  33
                         extractFile(input, destination, filter, entry);
    -  207   +  200  0
                     } else {
    +  201  264
                         extractFile(input, destination, filter, entry);
    +  202  
                     }
    +  203   +
                 }
    +  204  0
             } catch (IOException ex) {
    +  205  0
                 throw new ArchiveExtractionException(ex);
    +  206  0
             } catch (Throwable ex) {
    +  207  0
                 throw new ArchiveExtractionException(ex);
     208   -
                 }
    -  209  0
             } catch (IOException ex) {
    -  210  0
                 throw new ArchiveExtractionException(ex);
    -  211  0
             } catch (Throwable ex) {
    -  212  0
                 throw new ArchiveExtractionException(ex);
    -  213  
             } finally {
    -  214  3
                 closeStream(input);
    -  215  3
             }
    -  216  3
         }
    -  217   +  209  24
                 closeStream(input);
    +  210  24
             }
    +  211  24
         }
    +  212  
     
    -  218   +  213  
         /**
    -  219   +  214  
          * Extracts a file from an archive (input stream) and correctly builds the directory structure.
    -  220   +  215  
          *
    -  221   +  216  
          * @param input the archive input stream
    -  222   +  217  
          * @param destination where to write the file
    -  223   +  218  
          * @param filter the file filter to apply to the files being extracted
    -  224   +  219  
          * @param entry the entry from the archive to extract
    -  225   +  220  
          * @throws ExtractionException thrown if there is an error reading from the archive stream
    -  226   +  221  
          */
    -  227   +  222  
         private static void extractFile(ArchiveInputStream input, File destination,
    -  228   +  223  
                 FilenameFilter filter, ArchiveEntry entry) throws ExtractionException {
    -  229  33
             final File file = new File(destination, entry.getName());
    -  230  33
             if (filter.accept(file.getParentFile(), file.getName())) {
    -  231  3
                 final String extracting = String.format("Extracting '%s'",
    -  232   +  224  264
             final File file = new File(destination, entry.getName());
    +  225  264
             if (filter.accept(file.getParentFile(), file.getName())) {
    +  226  24
                 LOGGER.debug("Extracting '{}'",
    +  227  
                         file.getPath());
    -  233  3
                 LOGGER.fine(extracting);
    -  234  3
                 BufferedOutputStream bos = null;
    -  235  3
                 FileOutputStream fos = null;
    -  236   +  228  24
                 BufferedOutputStream bos = null;
    +  229  24
                 FileOutputStream fos = null;
    +  230  
                 try {
    -  237  3
                     createParentFile(file);
    -  238  3
                     fos = new FileOutputStream(file);
    -  239  3
                     bos = new BufferedOutputStream(fos, BUFFER_SIZE);
    -  240  3
                     transferUsingBuffer(input, bos);
    -  241  0
                 } catch (FileNotFoundException ex) {
    -  242  0
                     LOGGER.log(Level.FINE, null, ex);
    -  243  0
                     final String msg = String.format("Unable to find file '%s'.",
    -  244   +  231  24
                     createParentFile(file);
    +  232  24
                     fos = new FileOutputStream(file);
    +  233  24
                     bos = new BufferedOutputStream(fos, BUFFER_SIZE);
    +  234  24
                     transferUsingBuffer(input, bos);
    +  235  0
                 } catch (FileNotFoundException ex) {
    +  236  0
                     LOGGER.debug("", ex);
    +  237  0
                     final String msg = String.format("Unable to find file '%s'.",
    +  238  
                             file.getName());
    -  245  0
                     throw new ExtractionException(msg, ex);
    -  246  0
                 } catch (IOException ex) {
    -  247  0
                     LOGGER.log(Level.FINE, null, ex);
    -  248  0
                     final String msg = String
    -  249   +  239  0
                     throw new ExtractionException(msg, ex);
    +  240  0
                 } catch (IOException ex) {
    +  241  0
                     LOGGER.debug("", ex);
    +  242  0
                     final String msg = String
    +  243  
                             .format("IO Exception while parsing file '%s'.",
    -  250   +  244  
                                     file.getName());
    -  251  0
                     throw new ExtractionException(msg, ex);
    -  252   +  245  0
                     throw new ExtractionException(msg, ex);
    +  246  
                 } finally {
    -  253  3
                     closeStream(bos);
    -  254  3
                     closeStream(fos);
    -  255  3
                 }
    -  256   +  247  24
                     closeStream(bos);
    +  248  24
                     closeStream(fos);
    +  249  24
                 }
    +  250  
             }
    -  257  33
         }
    -  258   +  251  264
         }
    +  252  
     
    -  259   +  253  
         /**
    -  260   +  254  
          * Transfers data from one stream to another using a buffer.
    -  261   +  255  
          *
    -  262   +  256  
          * @param input the input stream
    -  263   +  257  
          * @param bos the output stream
    -  264   +  258  
          * @throws IOException thrown if there is an error reading/writing to the streams
    -  265   +  259  
          */
    -  266   +  260  
         private static void transferUsingBuffer(InputStream input,
    -  267   +  261  
                 BufferedOutputStream bos) throws IOException {
    -  268   +  262  
             int count;
    -  269  3
             final byte[] data = new byte[BUFFER_SIZE];
    -  270  6
             while ((count = input.read(data, 0, BUFFER_SIZE)) != -1) {
    -  271  3
                 bos.write(data, 0, count);
    -  272   +  263  24
             final byte[] data = new byte[BUFFER_SIZE];
    +  264  48
             while ((count = input.read(data, 0, BUFFER_SIZE)) != -1) {
    +  265  24
                 bos.write(data, 0, count);
    +  266  
             }
    -  273  3
             bos.flush();
    -  274  3
         }
    -  275   +  267  24
             bos.flush();
    +  268  24
         }
    +  269  
     
    -  276   +  270  
         /**
    -  277   +  271  
          * Closes the stream.
    -  278   +  272  
          *
    -  279   +  273  
          * @param stream the stream to close
    -  280   +  274  
          */
    -  281   +  275  
         private static void closeStream(Closeable stream) {
    -  282  9
             if (stream != null) {
    -  283   +  276  72
             if (stream != null) {
    +  277  
                 try {
    -  284  9
                     stream.close();
    -  285  0
                 } catch (IOException ex) {
    -  286  0
                     LOGGER.log(Level.FINEST, null, ex);
    -  287  9
                 }
    -  288   +  278  72
                     stream.close();
    +  279  0
                 } catch (IOException ex) {
    +  280  0
                     LOGGER.trace("", ex);
    +  281  72
                 }
    +  282  
             }
    -  289  9
         }
    -  290   +  283  72
         }
    +  284  
     
    -  291   +  285  
         /**
    -  292   +  286  
          * Ensures the parent path is correctly created on disk so that the file can be extracted to the correct location.
    -  293   +  287  
          *
    -  294   +  288  
          * @param file the file path
    -  295   +  289  
          * @throws ExtractionException thrown if the parent paths could not be created
    -  296   +  290  
          */
    -  297   +  291  
         private static void createParentFile(final File file)
    -  298   +  292  
                 throws ExtractionException {
    -  299  3
             final File parent = file.getParentFile();
    -  300  3
             if (!parent.isDirectory()) {
    -  301  3
                 if (!parent.mkdirs()) {
    -  302  0
                     final String msg = String.format(
    -  303   +  293  24
             final File parent = file.getParentFile();
    +  294  24
             if (!parent.isDirectory()) {
    +  295  24
                 if (!parent.mkdirs()) {
    +  296  0
                     final String msg = String.format(
    +  297  
                             "Unable to build directory '%s'.",
    -  304   +  298  
                             parent.getAbsolutePath());
    -  305  0
                     throw new ExtractionException(msg);
    -  306   +  299  0
                     throw new ExtractionException(msg);
    +  300  
                 }
    -  307   +  301  
             }
    -  308  3
         }
    -  309   -
     
    -  310   +  302  24
         }
    +  303  
     }
    - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.FileFilterBuilder.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.FileFilterBuilder.html new file mode 100644 index 000000000..5c8625548 --- /dev/null +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.FileFilterBuilder.html @@ -0,0 +1,275 @@ + + + + +Coverage Report + + + + +
    Coverage Report - org.owasp.dependencycheck.utils.FileFilterBuilder
    +
     
    + + + + +
    Classes in this File Line Coverage Branch Coverage Complexity
    FileFilterBuilder
    96%
    24/25
    81%
    13/16
    2.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) 2015 Institute for Defense Analyses. All Rights Reserved.
     17  
      */
     18  
     package org.owasp.dependencycheck.utils;
     19  
     
     20  
     import org.apache.commons.io.IOCase;
     21  
     import org.apache.commons.io.filefilter.IOFileFilter;
     22  
     import org.apache.commons.io.filefilter.NameFileFilter;
     23  
     import org.apache.commons.io.filefilter.OrFileFilter;
     24  
     import org.apache.commons.io.filefilter.SuffixFileFilter;
     25  
     
     26  
     import java.io.FileFilter;
     27  
     import java.util.ArrayList;
     28  
     import java.util.Arrays;
     29  
     import java.util.HashSet;
     30  
     import java.util.List;
     31  
     import java.util.Set;
     32  
     
     33  
     /**
     34  
      * <p>
     35  
      * Utility class for building useful {@link FileFilter} instances for
     36  
      * {@link org.owasp.dependencycheck.analyzer.AbstractFileTypeAnalyzer} implementations. The built filter uses {@link OrFileFilter}
     37  
      * to logically OR the given filter conditions. Example usage:</p>
     38  
      *
     39  
      * <pre>
     40  
      *     FileFilter filter = FileFilterBuilder.newInstance().addExtensions("jar", "war").build();
     41  
      * </pre>
     42  
      *
     43  
      * @author Dale Visser <dvisser@ida.org>
     44  
      * @see <a href="https://en.wikipedia.org/wiki/Builder_pattern">Builder pattern</a>
     45  
      */
     46  128
     public class FileFilterBuilder {
     47  
     
     48  
         /**
     49  
          * A set of filenames to filter.
     50  
          */
     51  128
         private final Set<String> filenames = new HashSet<String>();
     52  
         /**
     53  
          * A set of extensions to filter.
     54  
          */
     55  128
         private final Set<String> extensions = new HashSet<String>();
     56  
         /**
     57  
          * An array list of file filters.
     58  
          */
     59  128
         private final List<IOFileFilter> fileFilters = new ArrayList<IOFileFilter>();
     60  
     
     61  
         /**
     62  
          * Create a new instance and return it. This method is for convenience in using the builder pattern within a single statement.
     63  
          *
     64  
          * @return a new builder instance
     65  
          */
     66  
         public static FileFilterBuilder newInstance() {
     67  128
             return new FileFilterBuilder();
     68  
         }
     69  
     
     70  
         /**
     71  
          * Add to the set of filenames to accept for analysis. Case-sensitivity is assumed.
     72  
          *
     73  
          * @param names one or more filenames to accept for analysis
     74  
          * @return this builder
     75  
          */
     76  
         public FileFilterBuilder addFilenames(String... names) {
     77  24
             filenames.addAll(Arrays.asList(names));
     78  24
             return this;
     79  
         }
     80  
     
     81  
         /**
     82  
          * Add to the set of file extensions to accept for analysis. Case-insensitivity is assumed.
     83  
          *
     84  
          * @param extensions one or more file extensions to accept for analysis
     85  
          * @return this builder
     86  
          */
     87  
         public FileFilterBuilder addExtensions(String... extensions) {
     88  112
             return this.addExtensions(Arrays.asList(extensions));
     89  
         }
     90  
     
     91  
         /**
     92  
          * Add to the set of file extensions to accept for analysis. Case-insensitivity is assumed.
     93  
          *
     94  
          * @param extensions one or more file extensions to accept for analysis
     95  
          * @return this builder
     96  
          */
     97  
         public FileFilterBuilder addExtensions(Iterable<String> extensions) {
     98  120
             for (String extension : extensions) {
     99  
                 // Ultimately, SuffixFileFilter will be used, and the "." needs to be explicit.
     100  272
                 this.extensions.add(extension.startsWith(".") ? extension : "." + extension);
     101  272
             }
     102  120
             return this;
     103  
         }
     104  
     
     105  
         /**
     106  
          * Add to a list of {@link IOFileFilter} instances to consult for whether to accept a file for analysis.
     107  
          *
     108  
          * @param filters one or more file filters to consult for whether to accept for analysis
     109  
          * @return this builder
     110  
          */
     111  
         public FileFilterBuilder addFileFilters(IOFileFilter... filters) {
     112  8
             fileFilters.addAll(Arrays.asList(filters));
     113  8
             return this;
     114  
         }
     115  
     
     116  
         /**
     117  
          * Builds the filter and returns it.
     118  
          *
     119  
          * @return a filter that is the logical OR of all the conditions provided by the add... methods
     120  
          * @throws IllegalStateException if no add... method has been called with one or more arguments
     121  
          */
     122  
         public FileFilter build() {
     123  128
             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  128
             final OrFileFilter filter = new OrFileFilter();
     127  128
             if (!filenames.isEmpty()) {
     128  24
                 filter.addFileFilter(new NameFileFilter(new ArrayList<String>(filenames)));
     129  
             }
     130  128
             if (!extensions.isEmpty()) {
     131  120
                 filter.addFileFilter(new SuffixFileFilter(new ArrayList<String>(extensions), IOCase.INSENSITIVE));
     132  
             }
     133  128
             for (IOFileFilter iof : fileFilters) {
     134  16
                 filter.addFileFilter(iof);
     135  16
             }
     136  128
             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 ed0ad89d8..6800228ab 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.Filter.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.Filter.html @@ -47,7 +47,7 @@
      * https://plus.google.com/115403795880834599019/?rel=author
     14  
      */
    -  15  6
     public abstract class Filter<T> {
    +  15  48
     public abstract class Filter<T> {
     16  
     
     17   @@ -56,19 +56,19 @@
     
     19  
         public Iterator<T> filter(Iterator<T> iterator) {
    -  20  154
             return new FilterIterator(iterator);
    +  20  1144
             return new FilterIterator(iterator);
     21  
         }
     22  
     
     23  
         public Iterable<T> filter(final Iterable<T> iterable) {
    -  24  154
             return new Iterable<T>() {
    +  24  1144
             return new Iterable<T>() {
     25  
     
     26  
                 public Iterator<T> iterator() {
    -  27  154
                     return filter(iterable.iterator());
    +  27  1144
                     return filter(iterable.iterator());
     28  
                 }
     29   @@ -77,7 +77,7 @@
         }
     31  
     
    -  32  6
         private class FilterIterator implements Iterator<T> {
    +  32  48
         private class FilterIterator implements Iterator<T> {
     33  
     
     34   @@ -86,28 +86,28 @@
             private T next;
     36  
     
    -  37  154
             private FilterIterator(Iterator<T> iterator) {
    -  38  154
                 this.iterator = iterator;
    -  39  154
                 toNext();
    -  40  154
             }
    +  37  1144
             private FilterIterator(Iterator<T> iterator) {
    +  38  1144
                 this.iterator = iterator;
    +  39  1144
                 toNext();
    +  40  1144
             }
     41  
     
     42  
             public boolean hasNext() {
    -  43  927
                 return next != null;
    +  43  6360
                 return next != null;
     44  
             }
     45  
     
     46  
             public T next() {
    -  47  821
                 if (next == null) {
    +  47  5608
                 if (next == null) {
     48  0
                     throw new NoSuchElementException();
     49  
                 }
    -  50  821
                 T returnValue = next;
    -  51  821
                 toNext();
    -  52  821
                 return returnValue;
    +  50  5608
                 T returnValue = next;
    +  51  5608
                 toNext();
    +  52  5608
                 return returnValue;
     53  
             }
     54   @@ -121,22 +121,22 @@
     
     59  
             private void toNext() {
    -  60  975
                 next = null;
    -  61  1564
                 while (iterator.hasNext()) {
    -  62  1457
                     T item = iterator.next();
    -  63  1457
                     if (item != null && passes(item)) {
    -  64  868
                         next = item;
    -  65  868
                         break;
    +  60  6752
                 next = null;
    +  61  10840
                 while (iterator.hasNext()) {
    +  62  10080
                     T item = iterator.next();
    +  63  10080
                     if (item != null && passes(item)) {
    +  64  5992
                         next = item;
    +  65  5992
                         break;
     66  
                     }
    -  67  589
                 }
    -  68  975
             }
    +  67  4088
                 }
    +  68  6752
             }
     69  
         }
     70  
     }
    - + diff --git a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.NonClosingStream.html b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.NonClosingStream.html index 95c272916..4274d2da3 100644 --- a/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.NonClosingStream.html +++ b/dependency-check-core/cobertura/org.owasp.dependencycheck.utils.NonClosingStream.html @@ -110,6 +110,6 @@
     }
    - + 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 2044da0f9..d8cb80267 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  24879
         public Pair(L left, R right) {
    -  43  24879
             this.left = left;
    -  44  24879
             this.right = right;
    -  45  24879
         }
    +  42  201178
         public Pair(L left, R right) {
    +  43  201178
             this.left = left;
    +  44  201178
             this.right = right;
    +  45  201178
         }
     46  
         /**
     47  
          * The left element of the pair.
     48  
          */
    -  49  24879
         private L left = null;
    +  49  201178
         private L left = null;
     50  
     
     51   @@ -122,7 +122,7 @@
          */
     56  
         public L getLeft() {
    -  57  24879
             return left;
    +  57  201178
             return left;
     58  
         }
     59   @@ -147,7 +147,7 @@
          * The right element of the pair.
     70  
          */
    -  71  24879
         private R right = null;
    +  71  201178
         private R right = null;
     72  
     
     73   @@ -162,7 +162,7 @@
          */
     78  
         public R getRight() {
    -  79  24879
             return right;
    +  79  201178
             return right;
     80  
         }
     81   @@ -197,10 +197,10 @@
         @Override
     97  
         public int hashCode() {
    -  98  24891
             int hash = 3;
    -  99  24891
             hash = 53 * hash + (this.left != null ? this.left.hashCode() : 0);
    -  100  24891
             hash = 53 * hash + (this.right != null ? this.right.hashCode() : 0);
    -  101  24891
             return hash;
    +  98  201274
             int hash = 3;
    +  99  201274
             hash = 53 * hash + (this.left != null ? this.left.hashCode() : 0);
    +  100  201274
             hash = 53 * hash + (this.right != null ? this.right.hashCode() : 0);
    +  101  201274
             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 ddf175db0..0f1254540 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  8
         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  8
         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  22004
             return CONTAINS_URL_TEST.matcher(text).matches();
    +  57  154385
             return CONTAINS_URL_TEST.matcher(text).matches();
     58  
         }
     59   @@ -144,7 +144,7 @@
          */
     66  
         public static boolean isUrl(String text) {
    -  67  32
             return IS_URL_TEST.matcher(text).matches();
    +  67  264
             return IS_URL_TEST.matcher(text).matches();
     68  
         }
     69   @@ -153,7 +153,7 @@
          * A listing of domain parts that should not be used as evidence. Yes, this is an incomplete list.
     71  
          */
    -  72  1
         private static final Set<String> IGNORE_LIST = new HashSet<String>(
    +  72  8
         private static final Set<String> IGNORE_LIST = new HashSet<String>(
     73  
                 Arrays.asList("www", "com", "org", "gov", "info", "name", "net", "pro", "tel", "mobi", "xxx"));
     74   @@ -188,40 +188,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  200
             final List<String> importantParts = new ArrayList<String>();
    +  91  200
             final URL url = new URL(text);
    +  92  200
             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  576
             for (int i = 0; i < domain.length - 1; i++) {
    +  95  376
                 final String sub = domain[i];
    +  96  376
                 if (!IGNORE_LIST.contains(sub.toLowerCase())) {
    +  97  352
                     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  200
             final String document = url.getPath();
    +  101  200
             final String[] pathParts = document.split("[\\//]");
    +  102  352
             for (int i = 0; i < pathParts.length - 2; i++) {
    +  103  152
                 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  200
             if (pathParts.length > 0 && !pathParts[pathParts.length - 1].isEmpty()) {
    +  108  176
                 final String fileNameNoExt = pathParts[pathParts.length - 1].replaceAll("\\..*{0,5}$", "");
    +  109  176
                 importantParts.add(fileNameNoExt);
     110  
             }
    -  111  25
             return importantParts;
    +  111  200
             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 c4115bcbb..9c773c872 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  24
         public License(String name, String url) {
    +  39  24
             this.url = url;
    +  40  24
             this.name = name;
     41  
     
    -  42  3
         }
    +  42  24
         }
     43  
     
     44   @@ -221,24 +221,24 @@
         @Override
     110  
         public boolean equals(Object obj) {
    -  111  1
             if (obj == null) {
    +  111  8
             if (obj == null) {
     112  0
                 return false;
     113  
             }
    -  114  1
             if (getClass() != obj.getClass()) {
    +  114  8
             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  8
             final License other = (License) obj;
    +  118  8
             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  8
             if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
     122  0
                 return false;
     123  
             }
    -  124  1
             return true;
    +  124  8
             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 5a4787d8c..27fafc0c2 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 @@ -73,7 +73,7 @@
      * @author jeremy
     28  
      */
    -  29  23
     public class Model {
    +  29  184
     public class Model {
     30  
     
     31   @@ -98,7 +98,7 @@
          */
     41  
         public String getName() {
    -  42  4
             return name;
    +  42  32
             return name;
     43  
         }
     44   @@ -115,8 +115,8 @@
          */
     50  
         public void setName(String name) {
    -  51  5
             this.name = name;
    -  52  5
         }
    +  51  40
             this.name = name;
    +  52  40
         }
     53  
     
     54   @@ -141,7 +141,7 @@
          */
     64  
         public String getOrganization() {
    -  65  2
             return organization;
    +  65  16
             return organization;
     66  
         }
     67   @@ -158,8 +158,8 @@
          */
     73  
         public void setOrganization(String organization) {
    -  74  2
             this.organization = organization;
    -  75  2
         }
    +  74  16
             this.organization = organization;
    +  75  16
         }
     76  
     
     77   @@ -184,7 +184,7 @@
          */
     87  
         public String getDescription() {
    -  88  2
             return description;
    +  88  16
             return description;
     89  
         }
     90   @@ -201,8 +201,8 @@
          */
     96  
         public void setDescription(String description) {
    -  97  3
             this.description = description;
    -  98  3
         }
    +  97  24
             this.description = description;
    +  98  24
         }
     99  
     
     100   @@ -227,7 +227,7 @@
          */
     110  
         public String getGroupId() {
    -  111  2
             return groupId;
    +  111  16
             return groupId;
     112  
         }
     113   @@ -244,8 +244,8 @@
          */
     119  
         public void setGroupId(String groupId) {
    -  120  4
             this.groupId = groupId;
    -  121  4
         }
    +  120  32
             this.groupId = groupId;
    +  121  32
         }
     122  
     
     123   @@ -270,7 +270,7 @@
          */
     133  
         public String getArtifactId() {
    -  134  2
             return artifactId;
    +  134  16
             return artifactId;
     135  
         }
     136   @@ -287,8 +287,8 @@
          */
     142  
         public void setArtifactId(String artifactId) {
    -  143  4
             this.artifactId = artifactId;
    -  144  4
         }
    +  143  32
             this.artifactId = artifactId;
    +  144  32
         }
     145  
     
     146   @@ -313,7 +313,7 @@
          */
     156  
         public String getVersion() {
    -  157  2
             return version;
    +  157  16
             return version;
     158  
         }
     159   @@ -330,8 +330,8 @@
          */
     165  
         public void setVersion(String version) {
    -  166  3
             this.version = version;
    -  167  3
         }
    +  166  24
             this.version = version;
    +  167  24
         }
     168  
     
     169   @@ -356,7 +356,7 @@
          */
     179  
         public String getParentGroupId() {
    -  180  2
             return parentGroupId;
    +  180  16
             return parentGroupId;
     181  
         }
     182   @@ -373,8 +373,8 @@
          */
     188  
         public void setParentGroupId(String parentGroupId) {
    -  189  3
             this.parentGroupId = parentGroupId;
    -  190  3
         }
    +  189  24
             this.parentGroupId = parentGroupId;
    +  190  24
         }
     191  
     
     192   @@ -399,7 +399,7 @@
          */
     202  
         public String getParentArtifactId() {
    -  203  2
             return parentArtifactId;
    +  203  16
             return parentArtifactId;
     204  
         }
     205   @@ -416,8 +416,8 @@
          */
     211  
         public void setParentArtifactId(String parentArtifactId) {
    -  212  3
             this.parentArtifactId = parentArtifactId;
    -  213  3
         }
    +  212  24
             this.parentArtifactId = parentArtifactId;
    +  213  24
         }
     214  
     
     215   @@ -442,7 +442,7 @@
          */
     225  
         public String getParentVersion() {
    -  226  2
             return parentVersion;
    +  226  16
             return parentVersion;
     227  
         }
     228   @@ -459,8 +459,8 @@
          */
     234  
         public void setParentVersion(String parentVersion) {
    -  235  3
             this.parentVersion = parentVersion;
    -  236  3
         }
    +  235  24
             this.parentVersion = parentVersion;
    +  236  24
         }
     237  
     
     238   @@ -469,7 +469,7 @@
          * The list of licenses.
     240  
          */
    -  241  23
         private List<License> licenses = new ArrayList<License>();
    +  241  184
         private List<License> licenses = new ArrayList<License>();
     242  
     
     243   @@ -484,7 +484,7 @@
          */
     248  
         public List<License> getLicenses() {
    -  249  5
             return licenses;
    +  249  40
             return licenses;
     250  
         }
     251   @@ -501,8 +501,8 @@
          */
     257  
         public void addLicense(License license) {
    -  258  2
             licenses.add(license);
    -  259  2
         }
    +  258  16
             licenses.add(license);
    +  259  16
         }
     260  
     
     261   @@ -517,22 +517,22 @@
          */
     266  
         public void processProperties(Properties properties) {
    -  267  2
             this.groupId = interpolateString(this.groupId, properties);
    -  268  2
             this.artifactId = interpolateString(this.artifactId, properties);
    -  269  2
             this.version = interpolateString(this.version, properties);
    -  270  2
             this.description = interpolateString(this.description, properties);
    -  271  2
             for (License l : this.getLicenses()) {
    +  267  16
             this.groupId = interpolateString(this.groupId, properties);
    +  268  16
             this.artifactId = interpolateString(this.artifactId, properties);
    +  269  16
             this.version = interpolateString(this.version, properties);
    +  270  16
             this.description = interpolateString(this.description, properties);
    +  271  16
             for (License l : this.getLicenses()) {
     272  0
                 l.setName(interpolateString(l.getName(), properties));
     273  0
                 l.setUrl(interpolateString(l.getUrl(), properties));
     274  0
             }
    -  275  2
             this.name = interpolateString(this.name, properties);
    -  276  2
             this.organization = interpolateString(this.organization, properties);
    -  277  2
             this.parentGroupId = interpolateString(this.parentGroupId, properties);
    -  278  2
             this.parentArtifactId = interpolateString(this.parentArtifactId, properties);
    -  279  2
             this.parentVersion = interpolateString(this.parentVersion, properties);
    +  275  16
             this.name = interpolateString(this.name, properties);
    +  276  16
             this.organization = interpolateString(this.organization, properties);
    +  277  16
             this.parentGroupId = interpolateString(this.parentGroupId, properties);
    +  278  16
             this.parentArtifactId = interpolateString(this.parentArtifactId, properties);
    +  279  16
             this.parentVersion = interpolateString(this.parentVersion, properties);
     280  
     
    -  281  2
         }
    +  281  16
         }
     282  
     
     283   @@ -589,40 +589,40 @@
          */
     309  
         public static String interpolateString(String text, Properties properties) {
    -  310  31
             final Properties props = properties;
    -  311  31
             if (text == null) {
    -  312  11
                 return text;
    +  310  248
             final Properties props = properties;
    +  311  248
             if (text == null) {
    +  312  88
                 return text;
     313  
             }
    -  314  20
             if (props == null) {
    -  315  6
                 return text;
    +  314  160
             if (props == null) {
    +  315  48
                 return text;
     316  
             }
     317  
     
    -  318  14
             final int pos = text.indexOf("${");
    -  319  14
             if (pos < 0) {
    -  320  8
                 return text;
    +  318  112
             final int pos = text.indexOf("${");
    +  319  112
             if (pos < 0) {
    +  320  64
                 return text;
     321  
             }
    -  322  6
             final int end = text.indexOf("}");
    -  323  6
             if (end < pos) {
    +  322  48
             final int end = text.indexOf("}");
    +  323  48
             if (end < pos) {
     324  0
                 return text;
     325  
             }
     326  
     
    -  327  6
             final String propName = text.substring(pos + 2, end);
    -  328  6
             String propValue = interpolateString(props.getProperty(propName), props);
    -  329  6
             if (propValue == null) {
    +  327  48
             final String propName = text.substring(pos + 2, end);
    +  328  48
             String propValue = interpolateString(props.getProperty(propName), props);
    +  329  48
             if (propValue == null) {
     330  0
                 propValue = "";
     331  
             }
    -  332  6
             final StringBuilder sb = new StringBuilder(propValue.length() + text.length());
    -  333  6
             sb.append(text.subSequence(0, pos));
    -  334  6
             sb.append(propValue);
    -  335  6
             sb.append(text.substring(end + 1));
    -  336  6
             return interpolateString(sb.toString(), props); //yes yes, this should be a loop...
    +  332  48
             final StringBuilder sb = new StringBuilder(propValue.length() + text.length());
    +  333  48
             sb.append(text.subSequence(0, pos));
    +  334  48
             sb.append(propValue);
    +  335  48
             sb.append(text.substring(end + 1));
    +  336  48
             return interpolateString(sb.toString(), props); //yes yes, this should be a loop...
     337  
         }
     338   @@ -631,6 +631,6 @@
     }
    - + 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 eca305c3d..0edc67b04 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 @@ -77,7 +77,7 @@
      * @author Jeremy Long
     30  
      */
    -  31  2
     public class PomHandler extends DefaultHandler {
    +  31  16
     public class PomHandler extends DefaultHandler {
     32  
     
     33   @@ -176,7 +176,7 @@
          * The pom model.
     80  
          */
    -  81  2
         private Model model = new Model();
    +  81  16
         private Model model = new Model();
     82  
     
     83   @@ -191,7 +191,7 @@
          */
     88  
         public Model getModel() {
    -  89  2
             return model;
    +  89  16
             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  16
         private final Deque<String> stack = new ArrayDeque<String>();
     95  
         /**
     96  
          * The license object.
     97  
          */
    -  98  2
         private License license = null;
    +  98  16
         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 StringBuffer();
    -  117  471
             stack.push(qName);
    -  118  471
             if (LICENSE.equals(qName)) {
    +  116  3768
             currentText = new StringBuffer();
    +  117  3768
             stack.push(qName);
    +  118  3768
             if (LICENSE.equals(qName)) {
     119  0
                 license = new License();
     120  
             }
    -  121  471
         }
    +  121  3768
         }
     122  
     
     123   @@ -271,33 +271,33 @@
         @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  3768
             stack.pop();
    +  134  3768
             final String parentNode = stack.peek();
    +  135  3768
             if (PROJECT.equals(parentNode)) {
    +  136  232
                 if (GROUPID.equals(qName)) {
    +  137  16
                     model.setGroupId(currentText.toString());
    +  138  216
                 } else if (ARTIFACTID.equals(qName)) {
    +  139  16
                     model.setArtifactId(currentText.toString());
    +  140  200
                 } else if (VERSION.equals(qName)) {
    +  141  8
                     model.setVersion(currentText.toString());
    +  142  192
                 } else if (NAME.equals(qName)) {
    +  143  16
                     model.setName(currentText.toString());
    +  144  176
                 } else if (ORGANIZATION.equals(qName)) {
     145  0
                     model.setOrganization(currentText.toString());
    -  146  22
                 } else if (DESCRIPTION.equals(qName)) {
    -  147  1
                     model.setDescription(currentText.toString());
    +  146  176
                 } else if (DESCRIPTION.equals(qName)) {
    +  147  8
                     model.setDescription(currentText.toString());
     148  
                 }
    -  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());
    +  149  3536
             } else if (PARENT.equals(parentNode)) {
    +  150  24
                 if (GROUPID.equals(qName)) {
    +  151  8
                     model.setParentGroupId(currentText.toString());
    +  152  16
                 } else if (ARTIFACTID.equals(qName)) {
    +  153  8
                     model.setParentArtifactId(currentText.toString());
    +  154  8
                 } else if (VERSION.equals(qName)) {
    +  155  8
                     model.setParentVersion(currentText.toString());
     156  
                 }
    -  157  439
             } else if (LICENSE.equals(parentNode)) {
    +  157  3512
             } else if (LICENSE.equals(parentNode)) {
     158  0
                 if (license != null) {
     159  0
                     if (NAME.equals(qName)) {
     160  0
                         license.setName(currentText.toString());
    @@ -311,7 +311,7 @@
                     //TODO add error logging
     166  
                 }
    -  167  439
             } else if (LICENSES.equals(parentNode)) {
    +  167  3512
             } else if (LICENSES.equals(parentNode)) {
     168  0
                 if (LICENSE.equals(qName)) {
     169  0
                     if (license != null) {
     170  0
                         model.addLicense(license);
    @@ -325,7 +325,7 @@
                 }
     175  
             }
    -  176  471
         }
    +  176  3768
         }
     177  
     
     178   @@ -348,12 +348,12 @@
         @Override
     187  
         public void characters(char[] ch, int start, int length) throws SAXException {
    -  188  953
             currentText.append(ch, start, length);
    -  189  953
         }
    +  188  7624
             currentText.append(ch, start, length);
    +  189  7624
         }
     190  
     }
    - + 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 4cece1430..ea44c9678 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 @@ -137,6 +137,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 70b1bccc8..200923f77 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 @@ -70,145 +70,147 @@  26  
     import java.io.Reader;
     27   -
     import java.util.logging.Level;
    -  28   -
     import java.util.logging.Logger;
    -  29  
     import javax.xml.parsers.ParserConfigurationException;
    -  30   +  28  
     import javax.xml.parsers.SAXParser;
    -  31   +  29  
     import javax.xml.parsers.SAXParserFactory;
    +  30   +
     
    +  31   +
     import org.slf4j.Logger;
     32   -
     import org.xml.sax.InputSource;
    +
     import org.slf4j.LoggerFactory;
     33   -
     import org.xml.sax.SAXException;
    +
     import org.xml.sax.InputSource;
     34   -
     import org.xml.sax.XMLReader;
    +
     import org.xml.sax.SAXException;
     35   -
     
    +
     import org.xml.sax.XMLReader;
     36   -
     /**
    +
     
     37   -
      * A parser for pom.xml files.
    +
     /**
     38   -
      *
    +
      * A parser for pom.xml files.
     39   -
      * @author Jeremy Long
    +
      *
     40   +
      * @author Jeremy Long
    +  41  
      */
    -  41  2
     public class PomParser {
    -  42   -
     
    +  42  16
     public class PomParser {
     43   -
         /**
    +
     
     44   -
          * The logger.
    +
         /**
     45   +
          * The logger.
    +  46  
          */
    -  46  1
         private static final Logger LOGGER = Logger.getLogger(PomParser.class.getName());
    -  47   -
     
    +  47  8
         private static final Logger LOGGER = LoggerFactory.getLogger(PomParser.class);
     48   -
         /**
    +
     
     49   -
          * Parses the given xml file and returns a Model object containing only the fields dependency-check requires.
    -  50   -
          *
    -  51   -
          * @param file a pom.xml
    -  52   -
          * @return a Model object containing only the fields dependency-check requires
    -  53   -
          * @throws PomParseException thrown if the xml file cannot be parsed
    -  54   -
          */
    -  55   -
         public Model parse(File file) throws PomParseException {
    -  56  1
             FileInputStream fis = null;
    -  57   -
             try {
    -  58  1
                 fis = new FileInputStream(file);
    -  59  1
                 return parse(fis);
    -  60  0
             } catch (IOException ex) {
    -  61  0
                 LOGGER.log(Level.FINE, null, ex);
    -  62  0
                 throw new PomParseException(ex);
    -  63   -
             } finally {
    -  64  1
                 if (fis != null) {
    -  65   -
                     try {
    -  66  1
                         fis.close();
    -  67  0
                     } catch (IOException ex) {
    -  68  0
                         LOGGER.log(Level.FINE, "Unable to close stream", ex);
    -  69  2
                     }
    -  70   -
                 }
    -  71   -
             }
    -  72   -
         }
    -  73   -
     
    -  74  
         /**
    -  75   -
          * Parses the given XML file and returns a Model object containing only the fields dependency-check requires.
    -  76   +  50   +
          * Parses the given xml file and returns a Model object containing only the fields dependency-check requires.
    +  51  
          *
    -  77   -
          * @param inputStream an InputStream containing suppression rues
    -  78   -
          * @return a list of suppression rules
    -  79   -
          * @throws PomParseException if the XML cannot be parsed
    -  80   +  52   +
          * @param file a pom.xml
    +  53   +
          * @return a Model object containing only the fields dependency-check requires
    +  54   +
          * @throws PomParseException thrown if the xml file cannot be parsed
    +  55  
          */
    -  81   -
         public Model parse(InputStream inputStream) throws PomParseException {
    -  82   +  56   +
         public Model parse(File file) throws PomParseException {
    +  57  8
             FileInputStream fis = null;
    +  58  
             try {
    -  83  2
                 final PomHandler handler = new PomHandler();
    -  84  2
                 final SAXParserFactory factory = SAXParserFactory.newInstance();
    -  85   -
     //            factory.setNamespaceAware(true);
    -  86   -
     //            factory.setValidating(true);
    -  87  2
                 final SAXParser saxParser = factory.newSAXParser();
    -  88  2
                 final XMLReader xmlReader = saxParser.getXMLReader();
    -  89  2
                 xmlReader.setContentHandler(handler);
    -  90   -
     
    -  91  2
                 final Reader reader = new InputStreamReader(inputStream, "UTF-8");
    -  92  2
                 final InputSource in = new InputSource(reader);
    -  93   -
                 //in.setEncoding("UTF-8");
    -  94   -
     
    -  95  2
                 xmlReader.parse(in);
    -  96   -
     
    -  97  2
                 return handler.getModel();
    -  98  0
             } catch (ParserConfigurationException ex) {
    -  99  0
                 LOGGER.log(Level.FINE, null, ex);
    -  100  0
                 throw new PomParseException(ex);
    -  101  0
             } catch (SAXException ex) {
    -  102  0
                 LOGGER.log(Level.FINE, null, ex);
    -  103  0
                 throw new PomParseException(ex);
    -  104  0
             } catch (FileNotFoundException ex) {
    -  105  0
                 LOGGER.log(Level.FINE, null, ex);
    -  106  0
                 throw new PomParseException(ex);
    -  107  0
             } catch (IOException ex) {
    -  108  0
                 LOGGER.log(Level.FINE, null, ex);
    -  109  0
                 throw new PomParseException(ex);
    -  110   +  59  8
                 fis = new FileInputStream(file);
    +  60  8
                 return parse(fis);
    +  61  0
             } catch (IOException ex) {
    +  62  0
                 LOGGER.debug("", ex);
    +  63  0
                 throw new PomParseException(ex);
    +  64   +
             } finally {
    +  65  8
                 if (fis != null) {
    +  66   +
                     try {
    +  67  8
                         fis.close();
    +  68  0
                     } catch (IOException ex) {
    +  69  0
                         LOGGER.debug("Unable to close stream", ex);
    +  70  16
                     }
    +  71   +
                 }
    +  72  
             }
    -  111   +  73  
         }
    +  74   +
     
    +  75   +
         /**
    +  76   +
          * Parses the given XML file and returns a Model object containing only the fields dependency-check requires.
    +  77   +
          *
    +  78   +
          * @param inputStream an InputStream containing suppression rues
    +  79   +
          * @return a list of suppression rules
    +  80   +
          * @throws PomParseException if the XML cannot be parsed
    +  81   +
          */
    +  82   +
         public Model parse(InputStream inputStream) throws PomParseException {
    +  83   +
             try {
    +  84  16
                 final PomHandler handler = new PomHandler();
    +  85  16
                 final SAXParserFactory factory = SAXParserFactory.newInstance();
    +  86   +
     //            factory.setNamespaceAware(true);
    +  87   +
     //            factory.setValidating(true);
    +  88  16
                 final SAXParser saxParser = factory.newSAXParser();
    +  89  16
                 final XMLReader xmlReader = saxParser.getXMLReader();
    +  90  16
                 xmlReader.setContentHandler(handler);
    +  91   +
     
    +  92  16
                 final Reader reader = new InputStreamReader(inputStream, "UTF-8");
    +  93  16
                 final InputSource in = new InputSource(reader);
    +  94   +
                 //in.setEncoding("UTF-8");
    +  95   +
     
    +  96  16
                 xmlReader.parse(in);
    +  97   +
     
    +  98  16
                 return handler.getModel();
    +  99  0
             } catch (ParserConfigurationException ex) {
    +  100  0
                 LOGGER.debug("", ex);
    +  101  0
                 throw new PomParseException(ex);
    +  102  0
             } catch (SAXException ex) {
    +  103  0
                 LOGGER.debug("", ex);
    +  104  0
                 throw new PomParseException(ex);
    +  105  0
             } catch (FileNotFoundException ex) {
    +  106  0
                 LOGGER.debug("", ex);
    +  107  0
                 throw new PomParseException(ex);
    +  108  0
             } catch (IOException ex) {
    +  109  0
                 LOGGER.debug("", ex);
    +  110  0
                 throw new PomParseException(ex);
    +  111   +
             }
     112   +
         }
    +  113  
     }
    - + 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 f2c31a205..130e47865 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 @@ -12,7 +12,7 @@
     
    - +
    Classes in this File Line Coverage Branch Coverage Complexity
    PomUtils
    28%
    14/49
    50%
    1/2
    4.25
    PomUtils
    32%
    14/43
    50%
    1/2
    4.25
     
    @@ -62,17 +62,17 @@  22  
     import java.util.jar.JarFile;
     23   -
     import java.util.logging.Level;
    -  24   -
     import java.util.logging.Logger;
    -  25  
     import java.util.zip.ZipEntry;
    -  26   +  24  
     import org.owasp.dependencycheck.analyzer.JarAnalyzer;
    -  27   +  25  
     import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
    -  28   +  26  
     import org.owasp.dependencycheck.dependency.Dependency;
    +  27   +
     import org.slf4j.Logger;
    +  28   +
     import org.slf4j.LoggerFactory;
     29  
     
     30   @@ -101,7 +101,7 @@
          * The logger.
     43  
          */
    -  44  1
         private static final Logger LOGGER = Logger.getLogger(PomUtils.class.getName());
    +  44  8
         private static final Logger LOGGER = LoggerFactory.getLogger(PomUtils.class);
     45  
     
     46   @@ -115,113 +115,103 @@  50  
          * @return returns a
     51   -
          * @throws AnalysisException is thrown if there is an exception extracting or parsing the POM
    +
          * @throws AnalysisException is thrown if there is an exception extracting or parsing the POM {@link Model} object
     52   -
          * {@link org.owasp.dependencycheck.jaxb.pom.generated.Model} object
    +
          */
     53   -
          */
    -  54  
         public static Model readPom(File file) throws AnalysisException {
    -  55  1
             Model model = null;
    -  56   +  54  8
             Model model = null;
    +  55  
             try {
    -  57  1
                 final PomParser parser = new PomParser();
    -  58  1
                 model = parser.parse(file);
    -  59  0
             } catch (PomParseException ex) {
    -  60  0
                 final String msg = String.format("Unable to parse pom '%s'", file.getPath());
    -  61  0
                 LOGGER.log(Level.WARNING, msg);
    -  62  0
                 LOGGER.log(Level.FINE, "", ex);
    -  63  0
                 throw new AnalysisException(ex);
    -  64  0
             } catch (IOException ex) {
    -  65  0
                 final String msg = String.format("Unable to parse pom '%s'(IO Exception)", file.getPath());
    -  66  0
                 LOGGER.log(Level.WARNING, msg);
    -  67  0
                 LOGGER.log(Level.FINE, "", ex);
    -  68  0
                 throw new AnalysisException(ex);
    -  69  0
             } catch (Throwable ex) {
    -  70  0
                 final String msg = String.format("Unexpected error during parsing of the pom '%s'", file.getPath());
    -  71  0
                 LOGGER.log(Level.WARNING, msg);
    -  72  0
                 LOGGER.log(Level.FINE, "", ex);
    -  73  0
                 throw new AnalysisException(ex);
    -  74  1
             }
    -  75  1
             return model;
    -  76   +  56  8
                 final PomParser parser = new PomParser();
    +  57  8
                 model = parser.parse(file);
    +  58  0
             } catch (PomParseException ex) {
    +  59  0
                 LOGGER.warn("Unable to parse pom '{}'", file.getPath());
    +  60  0
                 LOGGER.debug("", ex);
    +  61  0
                 throw new AnalysisException(ex);
    +  62  0
             } catch (IOException ex) {
    +  63  0
                 LOGGER.warn("Unable to parse pom '{}'(IO Exception)", file.getPath());
    +  64  0
                 LOGGER.debug("", ex);
    +  65  0
                 throw new AnalysisException(ex);
    +  66  0
             } catch (Throwable ex) {
    +  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  8
             }
    +  71  8
             return model;
    +  72  
         }
    -  77   +  73  
     
    -  78   +  74  
         /**
    -  79   +  75  
          * Retrieves the specified POM from a jar file and converts it to a Model.
    -  80   +  76  
          *
    -  81   +  77  
          * @param path the path to the pom.xml file within the jar file
    -  82   +  78  
          * @param jar the jar file to extract the pom from
    -  83   +  79  
          * @return returns a
    -  84   -
          * @throws AnalysisException is thrown if there is an exception extracting or parsing the POM
    -  85   -
          * {@link org.owasp.dependencycheck.jaxb.pom.generated.Model} object
    -  86   +  80   +
          * @throws AnalysisException is thrown if there is an exception extracting or parsing the POM {@link Model} object
    +  81  
          */
    -  87   +  82  
         public static Model readPom(String path, JarFile jar) throws AnalysisException {
    -  88  1
             final ZipEntry entry = jar.getEntry(path);
    -  89  1
             Model model = null;
    -  90  1
             if (entry != null) { //should never be null
    -  91   +  83  8
             final ZipEntry entry = jar.getEntry(path);
    +  84  8
             Model model = null;
    +  85  8
             if (entry != null) { //should never be null
    +  86  
                 try {
    -  92  1
                     final PomParser parser = new PomParser();
    -  93  1
                     model = parser.parse(jar.getInputStream(entry));
    -  94  1
                     LOGGER.fine(String.format("Read POM %s", path));
    -  95  0
                 } catch (SecurityException ex) {
    -  96  0
                     final String msg = String.format("Unable to parse pom '%s' in jar '%s'; invalid signature", path, jar.getName());
    -  97  0
                     LOGGER.log(Level.WARNING, msg);
    -  98  0
                     LOGGER.log(Level.FINE, null, ex);
    -  99  0
                     throw new AnalysisException(ex);
    -  100  0
                 } catch (IOException ex) {
    -  101  0
                     final String msg = String.format("Unable to parse pom '%s' in jar '%s' (IO Exception)", path, jar.getName());
    -  102  0
                     LOGGER.log(Level.WARNING, msg);
    -  103  0
                     LOGGER.log(Level.FINE, "", ex);
    -  104  0
                     throw new AnalysisException(ex);
    -  105  0
                 } catch (Throwable ex) {
    -  106  0
                     final String msg = String.format("Unexpected error during parsing of the pom '%s' in jar '%s'", path, jar.getName());
    -  107  0
                     LOGGER.log(Level.WARNING, msg);
    -  108  0
                     LOGGER.log(Level.FINE, "", ex);
    -  109  0
                     throw new AnalysisException(ex);
    -  110  1
                 }
    -  111   +  87  8
                     final PomParser parser = new PomParser();
    +  88  8
                     model = parser.parse(jar.getInputStream(entry));
    +  89  8
                     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);
    +  93  0
                     throw new AnalysisException(ex);
    +  94  0
                 } catch (IOException ex) {
    +  95  0
                     LOGGER.warn("Unable to parse pom '{}' in jar '{}' (IO Exception)", path, jar.getName());
    +  96  0
                     LOGGER.debug("", ex);
    +  97  0
                     throw new AnalysisException(ex);
    +  98  0
                 } catch (Throwable ex) {
    +  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  8
                 }
    +  103  
             }
    -  112  1
             return model;
    -  113   +  104  8
             return model;
    +  105  
         }
    -  114   +  106  
     
    -  115   +  107  
         /**
    -  116   +  108  
          * Reads in the pom file and adds elements as evidence to the given dependency.
    -  117   +  109  
          *
    -  118   +  110  
          * @param dependency the dependency being analyzed
    -  119   +  111  
          * @param pomFile the pom file to read
    -  120   +  112  
          * @throws AnalysisException is thrown if there is an exception parsing the pom
    -  121   +  113  
          */
    -  122   +  114  
         public static void analyzePOM(Dependency dependency, File pomFile) throws AnalysisException {
    -  123  0
             final Model pom = PomUtils.readPom(pomFile);
    -  124  0
             JarAnalyzer.setPomEvidence(dependency, pom, null);
    -  125  0
         }
    -  126   +  115  0
             final Model pom = PomUtils.readPom(pomFile);
    +  116  0
             JarAnalyzer.setPomEvidence(dependency, pom, null);
    +  117  0
         }
    +  118  
     }
    - + diff --git a/dependency-check-core/cpd.html b/dependency-check-core/cpd.html index 05a2d78c5..c93f2f792 100644 --- a/dependency-check-core/cpd.html +++ b/dependency-check-core/cpd.html @@ -1,13 +1,13 @@ - + dependency-check-core - CPD Results @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -175,18 +175,18 @@ Checkstyle -
  • - - - - PMD -
  • -
  • - CPD + CPD Report
  • +
  • + + + + PMD Report +
  • +
  • @@ -239,7 +239,7 @@

    CPD Results

    -

    The following document contains the results of PMD's CPD 5.0.5.

    +

    The following document contains the results of PMD's CPD 5.0.2.

    Duplications

    @@ -247,11 +247,77 @@ + + + + + +
    File Line
    org\owasp\dependencycheck\data\update\CpeUpdater.java145
    org\owasp\dependencycheck\data\update\nvd\DownloadTask.java247
    +
    +
        }
    +
    +    /**
    +     * Extracts the file contained in a gzip archive. The extracted file is placed in the exact same path as the file specified.
    +     *
    +     * @param file the archive file
    +     * @throws FileNotFoundException thrown if the file does not exist
    +     * @throws IOException thrown if there is an error extracting the file.
    +     */
    +    private void extractGzip(File file) throws FileNotFoundException, IOException {
    +        //TODO - move this to a util class as it is duplicative of (copy of) code in the DownloadTask
    +        final String originalPath = file.getPath();
    +        final File gzip = new File(originalPath + ".gz");
    +        if (gzip.isFile() && !gzip.delete()) {
    +            gzip.deleteOnExit();
    +        }
    +        if (!file.renameTo(gzip)) {
    +            throw new IOException("Unable to rename '" + file.getPath() + "'");
    +        }
    +        final File newfile = new File(originalPath);
    +
    +        final byte[] buffer = new byte[4096];
    +
    +        GZIPInputStream cin = null;
    +        FileOutputStream out = null;
    +        try {
    +            cin = new GZIPInputStream(new FileInputStream(gzip));
    +            out = new FileOutputStream(newfile);
    +
    +            int len;
    +            while ((len = cin.read(buffer)) > 0) {
    +                out.write(buffer, 0, len);
    +            }
    +        } finally {
    +            if (cin != null) {
    +                try {
    +                    cin.close();
    +                } catch (IOException ex) {
    +                    LOGGER.trace("ignore", ex);
    +                }
    +            }
    +            if (out != null) {
    +                try {
    +                    out.close();
    +                } catch (IOException ex) {
    +                    LOGGER.trace("ignore", ex);
    +                }
    +            }
    +            if (gzip.isFile()) {
    +                FileUtils.deleteQuietly(gzip);
    +            }
    +        }
    +    }
    +}
    + + + + + - + - + - + - + - + - + - + @@ -252,11 +252,11 @@ - + - + @@ -278,6 +278,102 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -289,6 +385,186 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -300,7 +576,7 @@ - + @@ -312,6 +588,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -340,47 +676,23 @@ - - - - - - - - - - - - - + - - - - - - - - - - - - - + @@ -389,70 +701,22 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - - - - - - - - - - - - - + @@ -460,23 +724,23 @@ - - - - - + + + + + - + - + @@ -485,58 +749,10 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -548,7 +764,7 @@ - + @@ -560,7 +776,7 @@ - + @@ -568,59 +784,35 @@ - - - - - - - - - - - - - + - + - + - - - - - - - - - - - - - + @@ -631,7 +823,7 @@ - + @@ -644,7 +836,7 @@ - + @@ -656,7 +848,7 @@ - + @@ -668,7 +860,7 @@ - + @@ -680,7 +872,7 @@ - + @@ -703,23 +895,23 @@

    Dependency Updates

    -

    com.google.code.findbugs:annotations

    +

    ch.qos.logback:logback-classic

    FileLine
    org\owasp\dependencycheck\analyzer\JarAnalyzer.java874
    888
    org\owasp\dependencycheck\analyzer\PythonDistributionAnalyzer.java227
    235
        public void initializeFileTypeAnalyzer() throws Exception {
    @@ -273,11 +339,10 @@
         @Override
         public void close() {
             if (tempFileLocation != null && tempFileLocation.exists()) {
    -            LOGGER.log(Level.FINE, "Attempting to delete temporary files");
    +            LOGGER.debug("Attempting to delete temporary files");
                 final boolean success = FileUtils.delete(tempFileLocation);
                 if (!success) {
    -                LOGGER.log(Level.WARNING,
    -                        "Failed to delete some temporary files, see the log for more details");
    +                LOGGER.warn("Failed to delete some temporary files, see the log for more details");
                 }
             }
         }
    @@ -296,10 +361,10 @@
     
    Line
    org\owasp\dependencycheck\analyzer\ArchiveAnalyzer.java165
    173
    org\owasp\dependencycheck\analyzer\JarAnalyzer.java873
    887
        @Override
    @@ -329,10 +394,10 @@
     
    Line
    org\owasp\dependencycheck\analyzer\ArchiveAnalyzer.java166
    174
    org\owasp\dependencycheck\analyzer\PythonDistributionAnalyzer.java227
    235
        public void initializeFileTypeAnalyzer() throws Exception {
    diff --git a/dependency-check-core/dependency-updates-report.html b/dependency-check-core/dependency-updates-report.html
    index 4e1df110c..85b552add 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
         
    @@ -54,7 +54,7 @@
                     
                         
                                   
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -175,16 +175,16 @@
  • - + - PMD + CPD Report
  • - + - CPD + PMD Report
  • @@ -244,7 +244,7 @@
  • # of dependencies using the latest version available10
    23
    # 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 update9
    11
    # of dependencies where the next version available is a minor version update12
    13
    # of dependencies where the next version available is a major version updateNext Major
    ch.qos.logbacklogback-classic1.1.3jar
    ch.qos.logbacklogback-core1.1.3jar
    com.google.code.findbugsannotations3.0.0jar
    com.h2databaseh21.3.176jar1.4.177
    com.sun.mailmailapi1.5.2jar1.5.3
    commons-clicommons-cli1.2jar1.3
    commons-iocommons-io2.4jar
    commons-langcommons-lang2.6jar
    junit junit 4.12
    org.apache.antant1.9.5jar1.9.6
    org.apache.antant-testutil1.9.5jar1.9.6
    org.apache.commonscommons-compress1.9jar
    org.apache.lucenelucene-analyzers-common4.7.2jar4.8.05.0.0
    org.apache.lucenelucene-core4.7.2jar4.8.05.0.0
    org.apache.lucenelucene-queryparser4.7.2jar4.8.05.0.0
    org.apache.lucenelucene-test-framework4.7.2jar4.8.05.0.0
    org.apache.mavenmaven-core3.3.3jar
    org.apache.mavenmaven-plugin-api3.3.3jar
    org.apache.mavenmaven-settings3.3.3jar
    org.apache.maven.plugin-testingmaven-plugin-testing-harness3.3.0jar
    org.apache.maven.plugin-toolsmaven-plugin-annotations3.4jar
    org.apache.maven.pluginsmaven-site-plugin3.4jar
    org.apache.maven.reportingmaven-reporting-api3.0jar
    org.apache.velocityvelocity1.7jar
    org.hamcrest hamcrest-core
    org.jmockit jmockit1.17-beta1 1.17
    org.jsoupjsoup1.7.2jar1.7.31.8.1
    org.slf4jslf4j-api1.7.12jar
    org.slf4jslf4j-ext1.7.12jar
    org.slf4jslf4j-jdk141.7.12jar
    org.slf4jslf4j-simple1.7.12jar
    Status Group IdNext Minor Next Major
    com.google.code.findbugsannotations3.0.0compilejar
    com.google.inject guice 3.0providedtest jar 4.0-beta 4.0
    com.h2databaseh21.3.176compilejar1.4.177
    com.hazelcast hazelcast 2.5providedtest jar 3.0
    com.sun.mailmailapi1.5.2compilejar1.5.3
    commons-iocommons-io2.4compilejar
    commons-langcommons-lang2.6compilejar
    net.sf.ehcache ehcache-core 2.2.0providedtest jar 2.3.0
    org.apache.axis2 axis2-adb 1.4.1providedjar1.5
    org.apache.axis2axis2-spring1.4.1providedtest jar 1.5
    org.apache.commonscommons-compress1.9compileorg.apache.axis2axis2-spring1.4.1test jar 1.5
    org.apache.geronimo.daytrader daytrader-ear 2.1.7providedtest ear
    org.apache.lucenelucene-analyzers-common4.7.2compilejar4.8.05.0.0
    org.apache.lucenelucene-core4.7.2compilejar4.8.05.0.0
    org.apache.lucenelucene-queryparser4.7.2compilejar4.8.05.0.0
    org.apache.lucenelucene-test-framework4.7.2testjar4.8.05.0.0
    org.apache.maven.scm maven-scm-provider-cvsexe 1.8.1providedtest jar org.apache.openjpa openjpa 2.0.1providedtest jar org.apache.struts struts2-core 2.1.2providedtest jar 2.2.1
    org.apache.velocityvelocity1.7compilejar
    org.dojotoolkit dojo-war 1.3.0providedtest war 1.3.1 1.4.2
    org.glassfish.main.admingui war 4.0providedtest war 4.1
    org.jsoupjsoup1.7.2compilejar1.7.31.8.1
    org.mortbay.jetty jetty 6.1.0providedtest jar 6.1H.22 org.owasp dependency-check-utils1.2.111.3.0 compile jarorg.springframework spring-webmvc 2.5.5providedtest jar org.springframework.retry spring-retry 1.1.0.RELEASEprovidedtest jar org.springframework.security spring-security-web 3.0.0.RELEASEprovidedtest jar uk.ltd.getahead dwr 1.1.1providedtest jar
    - + - + - + - + @@ -727,6 +919,54 @@
    Status  No newer versions available.
    Group Idcom.google.code.findbugs
    ch.qos.logback
    Artifact Idannotations
    logback-classic
    Current Version3.0.0
    1.1.3
    Scopecompile
    Classifier
    Type jar
    +

    ch.qos.logback:logback-core

    + + + + + + + + + + + + + + + + + + + + + +
    Status No newer versions available.
    Group Idch.qos.logback
    Artifact Idlogback-core
    Current Version1.1.3
    Scope
    Classifier
    Typejar
    +
    +

    com.google.code.findbugs:annotations

    + + + + + + + + + + + + + + + + + + + + + +
    Status No newer versions available.
    Group Idcom.google.code.findbugs
    Artifact Idannotations
    Current Version3.0.0
    Scope
    Classifier
    Typejar
    +

    com.google.inject:guice

    @@ -743,7 +983,7 @@ - + @@ -770,7 +1010,7 @@ - + @@ -797,7 +1037,7 @@ - + @@ -806,7 +1046,7 @@ -
    3.0
    Scopeprovided
    test
    Classifier
    1.3.176
    Scopecompile
    Classifier
    2.5
    Scopeprovided
    test
    Classifier
    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.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.5-EA 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.5-EA
    3.5.1 Latest Major

    com.sun.mail:mailapi

    @@ -824,7 +1064,7 @@ - + @@ -833,7 +1073,34 @@ -
    1.5.2
    Scopecompile
    Classifier
    jar
    Newer versions1.5.3 Next Incremental
    +1.5.3 Next Incremental
    1.5.4 Latest Incremental +
    +

    commons-cli:commons-cli

    + + + + + + + + + + + + + + + + + + + + + + + + +
    Status There is at least one newer minor version available. Minor updates are sometimes passive.
    Group Idcommons-cli
    Artifact Idcommons-cli
    Current Version1.2
    Scope
    Classifier
    Typejar
    Newer versions1.3 Next Minor
    1.3.1 Latest Minor

    commons-io:commons-io

    @@ -851,7 +1118,7 @@ - + @@ -875,7 +1142,7 @@ - + @@ -923,7 +1190,7 @@ - + @@ -934,6 +1201,60 @@
    2.4
    Scopecompile
    Classifier
    2.6
    Scopecompile
    Classifier
    2.2.0
    Scopeprovided
    test
    Classifier
    Newer versions 2.3.0 Next Minor
    2.3.1
    2.3.2
    2.3.3
    2.4.0
    2.4.1
    2.4.2
    2.4.3
    2.4.4
    2.4.5
    2.4.6
    2.4.7
    2.4.8
    2.5.0
    2.5.1
    2.5.2
    2.5.3
    2.5.4
    2.5.5
    2.5.6
    2.5.7
    2.6.0
    2.6.2
    2.6.3
    2.6.5
    2.6.6
    2.6.8
    2.6.9
    2.6.10
    2.6.11 Latest Minor
    +

    org.apache.ant:ant

    + + + + + + + + + + + + + + + + + + + + + + + + +
    Status There is at least one newer incremental version available. Incremental updates are typically passive.
    Group Idorg.apache.ant
    Artifact Idant
    Current Version1.9.5
    Scope
    Classifier
    Typejar
    Newer versions1.9.6 Next Incremental
    +
    +

    org.apache.ant:ant-testutil

    + + + + + + + + + + + + + + + + + + + + + + + + +
    Status There is at least one newer incremental version available. Incremental updates are typically passive.
    Group Idorg.apache.ant
    Artifact Idant-testutil
    Current Version1.9.5
    Scope
    Classifier
    Typejar
    Newer versions1.9.6 Next Incremental
    +

    org.apache.axis2:axis2-adb

    @@ -950,7 +1271,7 @@ - + @@ -959,7 +1280,7 @@ -
    1.4.1
    Scopeprovided
    test
    Classifier
    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 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 Latest Minor

    org.apache.axis2:axis2-spring

    @@ -977,7 +1298,7 @@ - + @@ -986,7 +1307,7 @@ -
    1.4.1
    Scopeprovided
    test
    Classifier
    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 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 Latest Minor

    org.apache.commons:commons-compress

    @@ -1004,7 +1325,7 @@ - + @@ -1028,7 +1349,7 @@ - + @@ -1052,7 +1373,7 @@ - + @@ -1061,7 +1382,7 @@ -
    1.9
    Scopecompile
    Classifier
    2.1.7
    Scopeprovided
    test
    Classifier
    4.7.2
    Scopecompile
    Classifier
    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 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 Latest Major

    org.apache.lucene:lucene-core

    @@ -1079,7 +1400,7 @@ - + @@ -1088,7 +1409,7 @@ -
    4.7.2
    Scopecompile
    Classifier
    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 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 Latest Major

    org.apache.lucene:lucene-queryparser

    @@ -1106,7 +1427,7 @@ - + @@ -1115,7 +1436,7 @@ -
    4.7.2
    Scopecompile
    Classifier
    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 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 Latest Major

    org.apache.lucene:lucene-test-framework

    @@ -1133,7 +1454,7 @@ - + @@ -1142,7 +1463,175 @@ -
    4.7.2
    Scopetest
    Classifier
    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 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 Latest Major +
    +

    org.apache.maven:maven-core

    + + + + + + + + + + + + + + + + + + + + + +
    Status No newer versions available.
    Group Idorg.apache.maven
    Artifact Idmaven-core
    Current Version3.3.3
    Scope
    Classifier
    Typejar
    +
    +

    org.apache.maven:maven-plugin-api

    + + + + + + + + + + + + + + + + + + + + + +
    Status No newer versions available.
    Group Idorg.apache.maven
    Artifact Idmaven-plugin-api
    Current Version3.3.3
    Scope
    Classifier
    Typejar
    +
    +

    org.apache.maven:maven-settings

    + + + + + + + + + + + + + + + + + + + + + +
    Status No newer versions available.
    Group Idorg.apache.maven
    Artifact Idmaven-settings
    Current Version3.3.3
    Scope
    Classifier
    Typejar
    +
    +

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

    + + + + + + + + + + + + + + + + + + + + + +
    Status No newer versions available.
    Group Idorg.apache.maven.plugin-testing
    Artifact Idmaven-plugin-testing-harness
    Current Version3.3.0
    Scope
    Classifier
    Typejar
    +
    +

    org.apache.maven.plugin-tools:maven-plugin-annotations

    + + + + + + + + + + + + + + + + + + + + + +
    Status No newer versions available.
    Group Idorg.apache.maven.plugin-tools
    Artifact Idmaven-plugin-annotations
    Current Version3.4
    Scope
    Classifier
    Typejar
    +
    +

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

    + + + + + + + + + + + + + + + + + + + + + +
    Status No newer versions available.
    Group Idorg.apache.maven.plugins
    Artifact Idmaven-site-plugin
    Current Version3.4
    Scope
    Classifier
    Typejar
    +
    +

    org.apache.maven.reporting:maven-reporting-api

    + + + + + + + + + + + + + + + + + + + + + +
    Status No newer versions available.
    Group Idorg.apache.maven.reporting
    Artifact Idmaven-reporting-api
    Current Version3.0
    Scope
    Classifier
    Typejar

    org.apache.maven.scm:maven-scm-provider-cvsexe

    @@ -1160,7 +1649,7 @@ - + @@ -1187,7 +1676,7 @@ - + @@ -1214,7 +1703,7 @@ - + @@ -1223,7 +1712,7 @@ -
    1.8.1
    Scopeprovided
    test
    Classifier
    2.0.1
    Scopeprovided
    test
    Classifier
    2.1.2
    Scopeprovided
    test
    Classifier
    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 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.24
    2.5-BETA1 Latest Minor

    org.apache.velocity:velocity

    @@ -1241,7 +1730,7 @@ - + @@ -1265,7 +1754,7 @@ - + @@ -1292,7 +1781,7 @@ - + @@ -1370,7 +1859,7 @@ - + @@ -1397,7 +1886,7 @@ - + @@ -1421,7 +1910,7 @@ - + @@ -1432,6 +1921,102 @@
    1.7
    Scopecompile
    Classifier
    1.3.0
    Scopeprovided
    test
    Classifier
    4.0
    Scopeprovided
    test
    Classifier
    1.7.2
    Scopecompile
    Classifier
    6.1.0
    Scopeprovided
    test
    Classifier
    dependency-check-utils
    Current Version1.2.11
    1.3.0
    Scope compile
    Type jar
    +

    org.slf4j:slf4j-api

    + + + + + + + + + + + + + + + + + + + + + +
    Status No newer versions available.
    Group Idorg.slf4j
    Artifact Idslf4j-api
    Current Version1.7.12
    Scope
    Classifier
    Typejar
    +
    +

    org.slf4j:slf4j-ext

    + + + + + + + + + + + + + + + + + + + + + +
    Status No newer versions available.
    Group Idorg.slf4j
    Artifact Idslf4j-ext
    Current Version1.7.12
    Scope
    Classifier
    Typejar
    +
    +

    org.slf4j:slf4j-jdk14

    + + + + + + + + + + + + + + + + + + + + + +
    Status No newer versions available.
    Group Idorg.slf4j
    Artifact Idslf4j-jdk14
    Current Version1.7.12
    Scope
    Classifier
    Typejar
    +
    +

    org.slf4j:slf4j-simple

    + + + + + + + + + + + + + + + + + + + + + +
    Status No newer versions available.
    Group Idorg.slf4j
    Artifact Idslf4j-simple
    Current Version1.7.12
    Scope
    Classifier
    Typejar
    +

    org.springframework:spring-webmvc

    @@ -1448,7 +2033,7 @@ - + @@ -1457,7 +2042,7 @@ -
    2.5.5
    Scopeprovided
    test
    Classifier
    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
    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 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
    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.2.0.RELEASE Latest Major

    org.springframework.retry:spring-retry

    @@ -1475,7 +2060,7 @@ - + @@ -1502,7 +2087,7 @@ - + @@ -1511,7 +2096,7 @@ -
    1.1.0.RELEASE
    Scopeprovided
    test
    Classifier
    3.0.0.RELEASE
    Scopeprovided
    test
    Classifier
    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 Latest Minor
    4.0.0.RELEASE Next Major
    4.0.1.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 Latest Minor
    4.0.0.RELEASE Next Major
    4.0.1.RELEASE
    4.0.2.RELEASE Latest Major

    uk.ltd.getahead:dwr

    @@ -1529,7 +2114,7 @@ - + diff --git a/dependency-check-core/failsafe-report.html b/dependency-check-core/failsafe-report.html index 84c2f4f2c..b78f7b8e5 100644 --- a/dependency-check-core/failsafe-report.html +++ b/dependency-check-core/failsafe-report.html @@ -1,13 +1,13 @@ - + dependency-check-core - Surefire Report @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -175,16 +175,16 @@
  • - + - PMD + CPD Report
  • - + - CPD + PMD Report
  • @@ -268,12 +268,12 @@ function toggleDisplay(elementId) {
  • - + -
    1.1.1
    Scopeprovided
    test
    Classifier
    Success Rate Time
    3334 0 0 0 100%149.385

    +181.723

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


    Package List

    @@ -294,7 +294,7 @@ function toggleDisplay(elementId) { 0 0 100% -26.572 +6.858 org.owasp.dependencycheck 1 @@ -302,31 +302,39 @@ function toggleDisplay(elementId) { 0 0 100% -54.005 +126.665 -org.owasp.dependencycheck.analyzer -18 +org.owasp.dependencycheck.data.update.nvd +1 0 0 0 100% -21.259 +15.925 -org.owasp.dependencycheck.data.update -3 +org.owasp.dependencycheck.analyzer +19 0 0 0 100% -41.096 +24.353 +org.owasp.dependencycheck.data.update +2 +0 +0 +0 +100% +1.621 + org.owasp.dependencycheck.data.nvdcve 9 0 0 0 100% -6.453
    +6.301

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

    org.owasp.dependencycheck.reporting

    @@ -348,7 +356,7 @@ function toggleDisplay(elementId) { 0 0 100% -26.572
    +6.858

    org.owasp.dependencycheck

    @@ -369,7 +377,28 @@ function toggleDisplay(elementId) { -
    0 0 100%54.005
    +126.665 +
    +

    org.owasp.dependencycheck.data.update.nvd

    + + + + + + + + + + + + + + + + + + +
    ClassTestsErrors FailuresSkippedSuccess RateTime
    NvdCveUpdaterIntegrationTest1000100%15.925

    org.owasp.dependencycheck.analyzer

    @@ -390,7 +419,7 @@ function toggleDisplay(elementId) { - + @@ -399,8 +428,17 @@ function toggleDisplay(elementId) { - + + + + + + + + + + @@ -408,7 +446,7 @@ function toggleDisplay(elementId) { -
    0 0 100%13.61
    15.404
    CPEAnalyzerIntegrationTest0 0 100%5.021
    6.347
    DependencyBundlingAnalyzerIntegrationTest1000100%0
    VulnerabilitySuppressionAnalyzerIntegrationTest 30 0 100%2.628
    +2.602

    org.owasp.dependencycheck.data.update

    @@ -422,6 +460,15 @@ function toggleDisplay(elementId) { + + + + + + + + + @@ -429,16 +476,7 @@ function toggleDisplay(elementId) { - - - - - - - - - -
    Success Rate Time
    CpeUpdaterIntegrationTest1000100%0
    NvdCveUpdaterIntegrationTest 10 0 100%38.936
    StandardUpdateIntegrationTest2000100%2.16
    +1.621

    org.owasp.dependencycheck.data.nvdcve

    @@ -459,7 +497,7 @@ function toggleDisplay(elementId) { - + @@ -468,7 +506,7 @@ function toggleDisplay(elementId) { -
    0 0 100%2.769
    3.167
    DatabasePropertiesIntegrationTest0 0 100%3.684

    +3.134

    Test Cases

    [Summary] [Package List] [Test Cases]

    @@ -478,15 +516,15 @@ function toggleDisplay(elementId) { testAnalyzeTar -2.605 +3.004 testAnalyzeTgz -6.294 +7.041 testAnalyze -0.874 +0.927 testGetAnalysisPhase @@ -494,26 +532,26 @@ function toggleDisplay(elementId) { testGetName -0.001 +0 testAnalyze_badZip -0.526 +0.522 testInitialize -0 +0.003 testAnalyzeTarGz -3.308 +3.904 testSupportsExtension -0 +0.001 -testGetSupportedExtensions +testSupportsExtensions 0.001

    CPEAnalyzerIntegrationTest

    @@ -521,112 +559,122 @@ function toggleDisplay(elementId) { testSearchCPE -1.53 +1.771 testDetermineCPE -1.252 +1.594 testDetermineIdentifiers -0.956 +1.282 testDetermineCPE_full -1.282 +1.699 testBuildSearch 0.001
    +

    DependencyBundlingAnalyzerIntegrationTest

    + + + + +
    testAnalyze0
    +

    VulnerabilitySuppressionAnalyzerIntegrationTest

    - + - + -
    testAnalyze2.627
    2.601
    testGetAnalysisPhase0.001
    0
    testGetName0
    +0.001

    CveDBIntegrationTest

    - + - + - + -
    testOpen1.057
    1.043
    testGetCPEs0.554
    0.525
    testGetVulnerabilities0.651
    1.074
    testGetMatchingSoftware0.507
    +0.525

    DatabasePropertiesIntegrationTest

    - + - + - + - + -
    testSave1.514
    1.035
    testGetProperty_String_String0.555
    0.528
    testGetProperties0.515
    0.52
    testGetProperty_String0.559
    0.522
    testIsEmpty0.541
    +0.529 +
    +

    CpeUpdaterIntegrationTest

    + + + + +
    testUpdate0
    +
    +

    NvdCveUpdaterIntegrationTest

    + + + + +
    testUpdate15.925

    NvdCveUpdaterIntegrationTest

    - -
    testUpdate38.936
    -
    -

    StandardUpdateIntegrationTest

    - - - - - - - -
    testOpenDataStores1.079
    testUpdatesNeeded1.081
    +1.621

    EngineIntegrationTest

    -
    testEngine54.005
    +126.665

    ReportGeneratorIntegrationTest

    - + diff --git a/dependency-check-core/findbugs.html b/dependency-check-core/findbugs.html index 8613cb9da..c0211abd0 100644 --- a/dependency-check-core/findbugs.html +++ b/dependency-check-core/findbugs.html @@ -1,13 +1,13 @@ - + dependency-check-core - FindBugs Bug Detector Report @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -177,16 +177,16 @@
  • - + - PMD + CPD Report
  • - + - CPD + PMD Report
  • @@ -252,7 +252,7 @@
  • - +
    testGenerateXMLReport26.571
    6.857
    testGenerateReport Errors Missing Classes
    119126 7 0 0
    @@ -263,35 +263,20 @@ Class Bugs -org.owasp.dependencycheck.Engine -1 - org.owasp.dependencycheck.analyzer.ArchiveAnalyzer 1 - + org.owasp.dependencycheck.analyzer.AssemblyAnalyzer 1 + +org.owasp.dependencycheck.analyzer.CMakeAnalyzer +1 org.owasp.dependencycheck.analyzer.FalsePositiveAnalyzer 2 -org.owasp.dependencycheck.analyzer.JavaScriptAnalyzer -1 -
    -

    org.owasp.dependencycheck.Engine

    - - - - - - - - - - - - -
    BugCategoryDetailsLinePriority
    Redundant nullcheck of extension, which is known to be non-null in org.owasp.dependencycheck.Engine.scanFile(File)STYLERCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE328Medium
    +org.owasp.dependencycheck.data.update.cpe.CPEHandler$Element +1

    org.owasp.dependencycheck.analyzer.ArchiveAnalyzer

    @@ -305,7 +290,7 @@ - +
    Redundant nullcheck of org.owasp.dependencycheck.analyzer.ArchiveAnalyzer.tempFileLocation, which is known to be non-null in org.owasp.dependencycheck.analyzer.ArchiveAnalyzer.close() STYLE RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE189197 Medium

    org.owasp.dependencycheck.analyzer.AssemblyAnalyzer

    @@ -320,8 +305,23 @@ org.owasp.dependencycheck.analyzer.AssemblyAnalyzer.initializeFileTypeAnalyzer() discards result of readLine after checking if it is nonnull STYLE RV_DONT_JUST_NULL_CHECK_READLINE -239 -Medium
    +249 +Medium +
    +

    org.owasp.dependencycheck.analyzer.CMakeAnalyzer

    + + + + + + + + + + + + +
    BugCategoryDetailsLinePriority
    Found reliance on default encoding in org.owasp.dependencycheck.analyzer.CMakeAnalyzer.analyzeSetVersionCommand(Dependency, Engine, String): String.getBytes()I18NDM_DEFAULT_ENCODING200High

    org.owasp.dependencycheck.analyzer.FalsePositiveAnalyzer

    @@ -335,16 +335,16 @@ - + - -
    Possible null pointer dereference of currentVersion on branch that might be infeasible in org.owasp.dependencycheck.analyzer.FalsePositiveAnalyzer.removeSpuriousCPE(Dependency) STYLE NP_NULL_ON_SOME_PATH_MIGHT_BE_INFEASIBLE179187 Medium
    Possible null pointer dereference of nextVersion on branch that might be infeasible in org.owasp.dependencycheck.analyzer.FalsePositiveAnalyzer.removeSpuriousCPE(Dependency) STYLE NP_NULL_ON_SOME_PATH_MIGHT_BE_INFEASIBLE179Medium
    +187 +Medium
    -

    org.owasp.dependencycheck.analyzer.JavaScriptAnalyzer

    +

    org.owasp.dependencycheck.data.update.cpe.CPEHandler$Element

    @@ -353,11 +353,11 @@ - - - - -
    BugLine Priority
    Found reliance on default encoding in org.owasp.dependencycheck.analyzer.JavaScriptAnalyzer.analyzeFileType(Dependency, Engine): new java.io.FileReader(File)I18NDM_DEFAULT_ENCODING115High
    +Should org.owasp.dependencycheck.data.update.cpe.CPEHandler$Element be a _static_ inner class? +PERFORMANCE +SIC_INNER_SHOULD_BE_STATIC +182-360 +Medium diff --git a/dependency-check-core/index.html b/dependency-check-core/index.html index 8bebb6364..e54a3bc55 100644 --- a/dependency-check-core/index.html +++ b/dependency-check-core/index.html @@ -1,13 +1,13 @@ - + dependency-check-core - About @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • diff --git a/dependency-check-core/issue-tracking.html b/dependency-check-core/issue-tracking.html index 813446d39..7b99c717a 100644 --- a/dependency-check-core/issue-tracking.html +++ b/dependency-check-core/issue-tracking.html @@ -1,13 +1,13 @@ - + dependency-check-core - Issue Tracking @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • diff --git a/dependency-check-core/license.html b/dependency-check-core/license.html index b872a1e57..8c8e0fac3 100644 --- a/dependency-check-core/license.html +++ b/dependency-check-core/license.html @@ -1,13 +1,13 @@ - + dependency-check-core - Project License @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • diff --git a/dependency-check-core/mail-lists.html b/dependency-check-core/mail-lists.html index 7d69b2ce8..13c876cf5 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 @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • diff --git a/dependency-check-core/plugin-updates-report.html b/dependency-check-core/plugin-updates-report.html index c76eba340..1fbbb8dec 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 @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -175,16 +175,16 @@
  • - + - PMD + CPD Report
  • - + - CPD + PMD Report
  • @@ -244,7 +244,7 @@ # of plugins using the latest version available -12 +15 # of plugins where the next version available is smaller than an incremental version update @@ -256,7 +256,7 @@ # of plugins where the next version available is a minor version update -6 +3 # of plugins where the next version available is a major version update @@ -279,20 +279,20 @@ Next Major Dependency status - + org.apache.maven.plugins maven-antrun-plugin -1.3 +1.8 + -1.4 org.apache.maven.plugins maven-assembly-plugin -2.5.3 +2.5.5 @@ -312,21 +312,21 @@ org.apache.maven.plugins maven-compiler-plugin -3.2 +3.3 - + org.apache.maven.plugins maven-dependency-plugin -2.9 - - 2.10 + + + @@ -359,14 +359,14 @@ - + org.apache.maven.plugins maven-gpg-plugin -1.5 - - 1.6 + + + @@ -382,7 +382,7 @@ org.apache.maven.plugins maven-jar-plugin -2.5 +2.6 @@ -392,17 +392,17 @@ org.apache.maven.plugins maven-plugin-plugin -3.3 +3.2 -3.4 +3.3 org.apache.maven.plugins maven-release-plugin -2.5.1 +2.5.2 @@ -442,7 +442,7 @@ org.codehaus.mojo appassembler-maven-plugin -1.9 +1.10 @@ -452,7 +452,7 @@ org.codehaus.mojo cobertura-maven-plugin -2.6 +2.7 @@ -479,7 +479,7 @@ - + @@ -488,10 +488,7 @@ - - - -
    Status There is at least one newer minor version available. Minor updates are sometimes passive.
     No newer versions available.
    Group Id org.apache.maven.plugins
    maven-antrun-plugin
    Current Version1.3
    Newer versions1.4 Next Minor
    1.5
    1.6
    1.7
    1.8 Latest Minor
    +1.8

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

    @@ -506,7 +503,7 @@ -
    maven-assembly-plugin
    Current Version2.5.3
    +2.5.5

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

    @@ -536,13 +533,13 @@ -
    maven-compiler-plugin
    Current Version3.2
    +3.3

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

    - + @@ -551,10 +548,7 @@ - - - -
    Status There is at least one newer minor version available. Minor updates are sometimes passive.
     No newer versions available.
    Group Id org.apache.maven.plugins
    maven-dependency-plugin
    Current Version2.9
    Newer versions2.10 Next Minor
    +2.10

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

    @@ -608,7 +602,7 @@
    - + @@ -617,10 +611,7 @@ - - - -
    Status There is at least one newer minor version available. Minor updates are sometimes passive.
     No newer versions available.
    Group Id org.apache.maven.plugins
    maven-gpg-plugin
    Current Version1.5
    Newer versions1.6 Next Minor
    +1.6

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

    @@ -650,7 +641,7 @@ -
    maven-jar-plugin
    Current Version2.5
    +2.6

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

    @@ -665,10 +656,10 @@ - + -
    maven-plugin-plugin
    Current Version3.3
    3.2
    Newer versions3.4 Next Minor
    +3.3 Next Minor
    3.4 Latest Minor

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

    @@ -683,7 +674,7 @@ -
    maven-release-plugin
    Current Version2.5.1
    +2.5.2

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

    @@ -746,7 +737,7 @@ -
    appassembler-maven-plugin
    Current Version1.9
    +1.10

    Plugin org.codehaus.mojo:cobertura-maven-plugin

    @@ -761,7 +752,7 @@ -
    cobertura-maven-plugin
    Current Version2.6
    +2.7 diff --git a/dependency-check-core/pmd.html b/dependency-check-core/pmd.html index fe6033ad5..eb481f1a9 100644 --- a/dependency-check-core/pmd.html +++ b/dependency-check-core/pmd.html @@ -1,13 +1,13 @@ - + dependency-check-core - PMD Results @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -175,18 +175,18 @@ Checkstyle -
  • - - PMD -
  • -
  • - + - CPD + CPD Report
  • +
  • + + PMD Report +
  • +
  • @@ -239,7 +239,7 @@

    PMD Results

    -

    The following document contains the results of PMD 5.0.5.

    +

    The following document contains the results of PMD 5.0.2.

    Files

    @@ -250,10 +250,10 @@ Line These nested if statements could be combined -361364 +366 - 369 These nested if statements could be combined -377380
    +380 - 383

    org/owasp/dependencycheck/analyzer/AssemblyAnalyzer.java

    @@ -261,125 +261,116 @@ + + + -
    Violation Line
    Avoid unused private fields such as 'MESSAGE_CONVERYOR'.81
    Avoid empty while statements239241
    +249 - 251

    org/owasp/dependencycheck/analyzer/CPEAnalyzer.java

    - + - + - - - - + - + -
    Violation Line
    Useless parentheses.224
    These nested if statements could be combined532537
    226
    These nested if statements could be combined533536
    534 - 539
    These nested if statements could be combined542545
    +535 - 538 + +These nested if statements could be combined +544 - 547

    org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzer.java

    - + - + -
    Violation Line
    These nested if statements could be combined215217
    +215 - 217

    org/owasp/dependencycheck/analyzer/FalsePositiveAnalyzer.java

    - + - - - -
    Violation Line
    These nested if statements could be combined105111
    These nested if statements could be combined168188
    +113 - 119 + +These nested if statements could be combined +176 - 196

    org/owasp/dependencycheck/analyzer/HintAnalyzer.java

    - + - + -
    Violation Line
    Useless parentheses.107
    +112

    org/owasp/dependencycheck/analyzer/JarAnalyzer.java

    - + - + -
    Violation Line
    Useless parentheses.372
    -
    -

    org/owasp/dependencycheck/analyzer/JavaScriptAnalyzer.java

    - - - - - - -
    ViolationLine
    Avoid unused local variables such as 'extractComments'.113
    +377

    org/owasp/dependencycheck/analyzer/NexusAnalyzer.java

    - + - + -
    Violation Line
    Useless parentheses.105
    +107

    org/owasp/dependencycheck/analyzer/NvdCveAnalyzer.java

    - + - + -
    Violation Line
    Useless parentheses.76
    +76 +
    +

    org/owasp/dependencycheck/analyzer/OpenSSLAnalyzer.java

    + + + + + + +
    ViolationLine
    Useless parentheses.77

    org/owasp/dependencycheck/analyzer/PythonDistributionAnalyzer.java

    - + - + -
    Violation Line
    These nested if statements could be combined277280
    +285 - 288

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

    - - - - - - - - -
    ViolationLine
    Useless parentheses.172
    Useless parentheses.175
    -
    -

    org/owasp/dependencycheck/data/nexus/NexusSearch.java

    - - - + + - -
    Violation Line
    Avoid unused private fields such as 'userName'.54
    Useless parentheses.172
    Avoid unused private fields such as 'password'.58
    +Useless parentheses. +175

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

    @@ -387,80 +378,38 @@ - - + + - - - -
    Violation Line
    Unnecessary use of fully qualified name 'java.util.ResourceBundle.getBundle' due to existing import 'java.util.ResourceBundle'76
    These nested if statements could be combined630 - 632
    These nested if statements could be combined632634
    These nested if statements could be combined741743
    +737 - 739

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

    - + - + -
    Violation Line
    Useless parentheses.192
    +193

    org/owasp/dependencycheck/data/update/EngineVersionCheck.java

    - + - + -
    Violation Line
    Useless parentheses.91
    +91
    -

    org/owasp/dependencycheck/data/update/StandardUpdate.java

    - - - - - - -
    ViolationLine
    Useless parentheses.119
    -
    -

    org/owasp/dependencycheck/dependency/Dependency.java

    - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    ViolationLine
    Useless parentheses.725
    Useless parentheses.728
    Useless parentheses.731
    Useless parentheses.734
    Useless parentheses.737
    Useless parentheses.740
    Useless parentheses.755
    Useless parentheses.758
    -
    -

    org/owasp/dependencycheck/dependency/Evidence.java

    +

    org/owasp/dependencycheck/data/update/NvdCveUpdater.java

    -
    Violation Line
    Useless parentheses.204
    +117

    org/owasp/dependencycheck/dependency/Identifier.java

    @@ -469,10 +418,10 @@ - + -
    Line
    Useless parentheses.186
    186
    Useless parentheses.189
    +189

    org/owasp/dependencycheck/dependency/Reference.java

    @@ -481,13 +430,13 @@ - + - + -
    Line
    Useless parentheses.109
    109
    Useless parentheses.112
    112
    Useless parentheses.115
    +115

    org/owasp/dependencycheck/dependency/Vulnerability.java

    @@ -496,7 +445,7 @@ -
    Line
    Useless parentheses.373
    +373

    org/owasp/dependencycheck/dependency/VulnerableSoftware.java

    @@ -505,13 +454,13 @@ - + - + -
    Line
    Useless parentheses.143
    141
    Useless parentheses.182
    180
    Useless parentheses.187
    +185

    org/owasp/dependencycheck/suppression/PropertyType.java

    @@ -520,7 +469,7 @@ -
    Line
    Useless parentheses.161
    +161

    org/owasp/dependencycheck/utils/DependencyVersion.java

    @@ -529,10 +478,10 @@ - + -
    Line
    Useless parentheses.135
    135
    Useless parentheses.196
    +196

    org/owasp/dependencycheck/utils/ExtractionUtil.java

    @@ -541,10 +490,10 @@ - + -
    Line
    These nested if statements could be combined198203
    193 - 198
    These nested if statements could be combined301306
    +295 - 300

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

    @@ -553,10 +502,10 @@ - + -
    Line
    Useless parentheses.118
    118
    Useless parentheses.121
    +121

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

    @@ -565,10 +514,10 @@ - + -
    Line
    These nested if statements could be combined168174
    168 - 174
    These nested if statements could be combined169173
    +169 - 173 diff --git a/dependency-check-core/project-info.html b/dependency-check-core/project-info.html index 47109d8b3..165c7006f 100644 --- a/dependency-check-core/project-info.html +++ b/dependency-check-core/project-info.html @@ -1,13 +1,13 @@ - + dependency-check-core - Project Information @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • diff --git a/dependency-check-core/project-reports.html b/dependency-check-core/project-reports.html index 8490bd61a..ccaae7bbc 100644 --- a/dependency-check-core/project-reports.html +++ b/dependency-check-core/project-reports.html @@ -1,13 +1,13 @@ - + dependency-check-core - Generated Reports @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -175,16 +175,16 @@
  • - + - PMD + CPD Report
  • - + - CPD + PMD Report
  • @@ -277,11 +277,11 @@ Checkstyle Report on coding style conventions. -PMD -Verification of coding rules. - -CPD +CPD Report Duplicate code detection. + +PMD Report +Verification of coding rules. FindBugs Report Generates a source code report with the FindBugs Library. diff --git a/dependency-check-core/project-summary.html b/dependency-check-core/project-summary.html index d6dc92a46..36b684c4e 100644 --- a/dependency-check-core/project-summary.html +++ b/dependency-check-core/project-summary.html @@ -1,13 +1,13 @@ - + dependency-check-core - Project Summary @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -231,7 +231,7 @@ dependency-check-core Version -1.2.11 +1.3.0 Type jar diff --git a/dependency-check-core/source-repository.html b/dependency-check-core/source-repository.html index 66143cfd2..4099fb31c 100644 --- a/dependency-check-core/source-repository.html +++ b/dependency-check-core/source-repository.html @@ -1,13 +1,13 @@ - + dependency-check-core - Source Repository @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • diff --git a/dependency-check-core/surefire-report.html b/dependency-check-core/surefire-report.html index 4b9b2e436..9f5b582dc 100644 --- a/dependency-check-core/surefire-report.html +++ b/dependency-check-core/surefire-report.html @@ -1,13 +1,13 @@ - + dependency-check-core - Surefire Report @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -175,16 +175,16 @@
  • - + - PMD + CPD Report
  • - + - CPD + PMD Report
  • @@ -268,12 +268,12 @@ function toggleDisplay(elementId) { Success Rate Time -200 +207 0 0 5 -97.5% -31.893
    +97.585% +54.396

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


    Package List

    @@ -304,45 +304,45 @@ function toggleDisplay(elementId) { 0% 0 -org.owasp.dependencycheck.dependency -27 +org.owasp.dependencycheck.data.update.nvd +13 0 0 0 100% -0.028 +41.271 +org.owasp.dependencycheck.dependency +26 +0 +0 +0 +100% +0.027 + org.owasp.dependencycheck.data.central 5 0 0 0 100% -0.439 - +0.461 + org.owasp.dependencycheck.analyzer -55 +59 0 0 1 -98.182% -7.891 - -org.owasp.dependencycheck.data.update.xml -2 -0 -0 -0 -100% -0.081 +98.305% +9.28 org.owasp.dependencycheck.data.update -12 +6 0 0 0 100% -0.357 +2.204 org.owasp.dependencycheck.suppression 37 @@ -350,7 +350,7 @@ function toggleDisplay(elementId) { 0 0 100% -0.014 +0.001 org.owasp.dependencycheck.xml.pom 23 @@ -374,7 +374,7 @@ function toggleDisplay(elementId) { 0 0 100% -0.026 +0.024 org.owasp.dependencycheck.utils 13 @@ -384,29 +384,21 @@ function toggleDisplay(elementId) { 100% 0.001 -org.owasp.dependencycheck.data.update.task -1 -0 -0 -0 -100% -22.329 - org.owasp.dependencycheck.data.nvdcve 6 0 0 0 100% -0.078 - +0.175 + org.owasp.dependencycheck.data.lucene 10 0 0 0 100% -0.649
    +0.952

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

    org.owasp.dependencycheck.data.cwe

    @@ -451,6 +443,63 @@ function toggleDisplay(elementId) { 0% 0
    +

    org.owasp.dependencycheck.data.update.nvd

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ClassTestsErrors FailuresSkippedSuccess RateTime
    DownloadTaskTest1000100%41.168
    NvdCveInfoTest5000100%0
    NvdCve_1_2_HandlerTest1000100%0.024
    NvdCve_2_0_HandlerTest1000100%0.079
    UpdateableNvdCveTest5000100%0
    +

    org.owasp.dependencycheck.dependency

    @@ -465,16 +514,16 @@ function toggleDisplay(elementId) { - + - + - + @@ -509,7 +558,7 @@ function toggleDisplay(elementId) { -
    DependencyTest2220 0 0 0 100%0.028
    0.027
    EvidenceTest23 0 0 00 0 100%0.439
    +0.461

    org.owasp.dependencycheck.analyzer

    @@ -530,7 +579,7 @@ function toggleDisplay(elementId) { - + @@ -539,7 +588,7 @@ function toggleDisplay(elementId) { - + @@ -548,7 +597,7 @@ function toggleDisplay(elementId) { - + @@ -557,7 +606,25 @@ function toggleDisplay(elementId) { - + + + + + + + + + + + + + + + + + + + @@ -584,7 +651,7 @@ function toggleDisplay(elementId) { - + @@ -593,82 +660,52 @@ function toggleDisplay(elementId) { - + - + - + - - - - - - - - - - + - - - - - - - - - - - + + -
    0 0 100%0.024
    0.031
    AbstractSuppressionAnalyzerTest0 0 100%0.563
    0.516
    AnalyzerServiceTest0 0 100%0.041
    0.075
    AssemblyAnalyzerTest0 1 80%0.487
    0.766
    AutoconfAnalyzerTest6000100%0.113
    CMakeAnalyzerTest5000100%0.988
    DependencyBundlingAnalyzerTest0 0 100%0.058
    0
    HintAnalyzerTest0 0 100%6.582
    6.634
    JarAnalyzerTest43 0 0 0 100%0.063
    0.097
    JavaScriptAnalyzerTest7000100%0.009
    NuspecAnalyzerTest43 0 0 0 100% 0
    PythonDistributionAnalyzerTest9000100%0.064
    PythonPackageAnalyzerTestOpenSSLAnalyzerTest 4 0 0 0 100%0
    -
    -

    org.owasp.dependencycheck.data.update.xml

    - + - - - - - - - - + + + + + + + + - - - + + + - - - - - - - - - -
    0.001
    ClassTestsErrors FailuresSkippedSuccess RateTime
    PythonDistributionAnalyzerTest8000100%0.059
    NvdCve_1_2_HandlerTest1PythonPackageAnalyzerTest3 0 0 0 100%0.023
    NvdCve_2_0_HandlerTest1000100%0.058
    +0

    org.owasp.dependencycheck.data.update

    @@ -682,6 +719,15 @@ function toggleDisplay(elementId) { + + + + + + + + + @@ -689,25 +735,7 @@ function toggleDisplay(elementId) { - - - - - - - - - - - - - - - - - - -
    Success Rate Time
    BaseUpdaterTest4000100%1.659
    EngineVersionCheckTest 20 0 100%0.357
    NvdCveInfoTest5000100%0
    UpdateableNvdCveTest5000100%0
    +0.545

    org.owasp.dependencycheck.suppression

    @@ -755,7 +783,7 @@ function toggleDisplay(elementId) { -
    0 0 100%0.014
    +0.001

    org.owasp.dependencycheck.xml.pom

    @@ -827,7 +855,7 @@ function toggleDisplay(elementId) { -
    0 0 100%0.026
    +0.024

    org.owasp.dependencycheck.utils

    @@ -857,7 +885,7 @@ function toggleDisplay(elementId) { - + @@ -875,28 +903,7 @@ function toggleDisplay(elementId) { -
    0 0 100%0.001
    0
    DependencyVersionUtilTest0 0 100%0
    -
    -

    org.owasp.dependencycheck.data.update.task

    - - - - - - - - - - - - - - - - - - -
    ClassTestsErrors FailuresSkippedSuccess RateTime
    DownloadTaskTest1000100%22.329
    +0.001

    org.owasp.dependencycheck.data.nvdcve

    @@ -917,7 +924,7 @@ function toggleDisplay(elementId) { -
    0 0 100%0.078
    +0.175

    org.owasp.dependencycheck.data.lucene

    @@ -956,7 +963,7 @@ function toggleDisplay(elementId) { - + @@ -965,7 +972,7 @@ function toggleDisplay(elementId) { -
    0 0 100%0.06
    0.069
    UrlTokenizingFilterTest0 0 100%0.589

    +0.883

    Test Cases

    [Summary] [Package List] [Test Cases]

    @@ -975,44 +982,44 @@ function toggleDisplay(elementId) { testNewHashSet -0.024
    +0.031

    AbstractSuppressionAnalyzerTest

    - + - + - + -
    testFailureToLocateSuppressionFileAnywhere0.41
    0.299
    testGetRulesFromSuppressionFileFromURL0.122
    0.182
    testGetRulesFromSuppressionFileInClasspath0.031
    0.034
    testGetSupportedExtensions0
    +0.001

    AnalyzerServiceTest

    -
    testGetAnalyzers0.041
    +0.075

    AssemblyAnalyzerTest

    - + - + - + -
    testGetName0.191
    0.322
    testAnalysis0.089
    0.139
    testWithSettingMono @@ -1025,11 +1032,61 @@ function toggleDisplay(elementId) {
    testNonexistent0.065
    0.097
    testLog4Net0.142
    +0.208 +
    +

    AutoconfAnalyzerTest

    + + + + + + + + + + + + + + + + + + + + + + + + +
    testAnalyzeReadableConfigureScript0.033
    testGetName0.001
    testSupportsFileExtension0.001
    testAnalyzeConfigureScript0.071
    testAnalyzeConfigureAC10.003
    testAnalyzeConfigureAC20.004
    +
    +

    CMakeAnalyzerTest

    + + + + + + + + + + + + + + + + + + + + +
    testAnalyzeCMakeListsZlib0
    testAnalyzeCMakeListsOpenCV0.008
    testGetName0.002
    testAnalyzeCMakeListsOpenCV3rdParty0.977
    testAccept0.001

    DependencyBundlingAnalyzerTest

    @@ -1074,7 +1131,7 @@ function toggleDisplay(elementId) { - + @@ -1097,7 +1154,7 @@ function toggleDisplay(elementId) { - + @@ -1112,69 +1169,49 @@ function toggleDisplay(elementId) { - + - - - - - - - - -
    testAnalyze0.058
    0
    testClose
    testAnalyze6.58
    6.632
    testGetAnalysisPhase
    testAnalyze0.062
    0.097
    testGetName0.001
    testSupportsExtension0
    testGetSupportedExtensions0
    -
    -

    JavaScriptAnalyzerTest

    - - - - - - - - - - - - - - - - - - - - - - - - - +
    testAnalyze0.006
    testClose 0
    testGetAnalysisPhase0.001
    testGetName0.001
    testInitialize0.001
    testSupportsExtension0
    testGetSupportedExtensionstestAcceptSupportedExtensions 0

    NuspecAnalyzerTest

    - + - + +
    testGetAnalysisPhazetestSupportsFileExtensions 0
    testSupportsExtensiontestGetAnalysisPhaze 0
    testGetAnalyzerName0
    +
    +

    OpenSSLAnalyzerTest

    + + + + - -
    testGetName 0
    testGetSupportedExtensions0
    +testVersionConstantExamples +0 + + +testOpenSSLVersionHeaderFile +0 + + +testAccept +0.001

    PythonDistributionAnalyzerTest

    @@ -1189,31 +1226,27 @@ function toggleDisplay(elementId) { - + - + - + - - - - - - - - - + -
    testAnalyzeEggArchive0.022
    0.016
    testAnalyzeEggArchiveNamedZip0.01
    0.012
    testAnalyzeWheel0.013
    0.014
    testSupportsExtension0.003
    testAnalyzeEggInfoFolder0.004
    testGetSupportedExtensions0.003
    0.005
    testAnalyzeSitePackage0.004
    +0.005 + + +testSupportsFiles +0.002

    PythonPackageAnalyzerTest

    @@ -1227,11 +1260,7 @@ function toggleDisplay(elementId) { - - - - - +
    0
    testSupportsExtension0
    testGetSupportedExtensionstestSupportsFileExtension 0

    CentralSearchTest

    @@ -1239,23 +1268,23 @@ function toggleDisplay(elementId) { testMultipleReturns -0.293 +0.292 testNullSha1 -0.001 +0 testMalformedSha1 -0 +0.001 testValidSha1 -0.081 +0.095 testMissingSha1 -0.064
    +0.073

    IndexEntryTest

    @@ -1301,27 +1330,27 @@ function toggleDisplay(elementId) {
    - - + + - -
    testClear0.051
    testExamples0.059
    testExamples0.009
    +testClear +0.01

    UrlTokenizingFilterTest

    - + - - + + - -
    testEmptyTerm0.015
    0.014
    testRandomStrings0.565
    testExamples0.051
    testExamples0.009
    +testRandomStrings +0.818

    NexusSearchTest

    @@ -1367,15 +1396,15 @@ function toggleDisplay(elementId) { - + - + -
    testGoodDocument0.007
    0.003
    testMissingDocument0.011
    0.014
    testNotNuspec0.008
    +0.007

    DriverLoaderTest

    @@ -1398,24 +1427,50 @@ function toggleDisplay(elementId) { - + -
    testLoad_String_String0.035
    0.027
    testLoad_String_String_multiple_paths0.043
    +0.148 +
    +

    BaseUpdaterTest

    + + + + + + + + + + + + + + + + +
    testGetCveDB0
    testOpenDataStores0.588
    testGetProperties0.539
    testCloseDataStores0.532

    EngineVersionCheckTest

    - + -
    testShouldUpdate0.258
    0.458
    testGetCurrentReleaseVersion0.099
    +0.087
    -

    NvdCveInfoTest

    +

    DownloadTaskTest

    + + + + +
    testCall41.168
    +
    +

    NvdCveInfoTest

    @@ -1438,14 +1493,21 @@ function toggleDisplay(elementId) {
    testSetGetId 0
    -

    DownloadTaskTest

    +

    NvdCve_1_2_HandlerTest

    - -
    testCall22.329
    +testParse +0.024
    -

    UpdateableNvdCveTest

    +

    NvdCve_2_0_HandlerTest

    + + + + +
    testParse0.079
    +
    +

    UpdateableNvdCveTest

    @@ -1468,20 +1530,6 @@ function toggleDisplay(elementId) {
    testIterator 0
    -

    NvdCve_1_2_HandlerTest

    - - - - -
    testParse0.023
    -
    -

    NvdCve_2_0_HandlerTest

    - - - - -
    testParse0.058
    -

    DependencyTest

    @@ -1491,71 +1539,63 @@ function toggleDisplay(elementId) { - + - + - + - + - + - - - - - + - + - + - + - + - + + + + + - - - - - - - - - + - + @@ -1581,6 +1621,10 @@ function toggleDisplay(elementId) { + + + +
    testGetSha1sum0.012
    0.009
    testGetProductEvidence0
    0.001
    testGetActualFilePath0.001
    0
    testAddAsEvidence0
    0.001
    testAddAsEvidenceWithEmptyArtefact0
    0.001
    testSetFileExtension0
    testGetIdentifiers 0
    testSetSha1sum 0
    testAddIdentifier 0
    testGetVendorEvidence 0
    testSetFileName 0
    testSetFilePath 0
    testGetFileName0.001
    testGetFilePath 0
    testGetFilePath0.001
    testGetFileExtension0.001
    testSetMd5sum0.001
    0
    testGetMd5sum0.011
    0.013
    testGetEvidence0
    testHashcodeContract0
    testEquals 0
    @@ -1665,11 +1709,11 @@ function toggleDisplay(elementId) { testHasCvssBelow -0.001 +0 testProcess -0.004 +0 testGetSha1 @@ -1677,7 +1721,7 @@ function toggleDisplay(elementId) { testProcessGAV -0.005 +0 testAddCvssBelow @@ -1685,7 +1729,7 @@ function toggleDisplay(elementId) { testFilePath -0.001 +0 testGetCvssBelow @@ -1697,7 +1741,7 @@ function toggleDisplay(elementId) { testGetFilePath -0.001 +0 testAddCpe @@ -1709,7 +1753,7 @@ function toggleDisplay(elementId) { testAddCwe -0.001 +0 testGetCpe @@ -1725,7 +1769,7 @@ function toggleDisplay(elementId) { testHasCpe -0 +0.001 testHasCve @@ -1745,7 +1789,7 @@ function toggleDisplay(elementId) { testSetCpe -0.001 +0 testSetCve @@ -1775,7 +1819,7 @@ function toggleDisplay(elementId) { testMatchesAtLeastThreeLevels -0.001 +0 testToString @@ -1817,7 +1861,7 @@ function toggleDisplay(elementId) { testFilter_Iterable -0 +0.001 testPasses diff --git a/dependency-check-core/taglist.html b/dependency-check-core/taglist.html index 0cc19ccae..4563e5357 100644 --- a/dependency-check-core/taglist.html +++ b/dependency-check-core/taglist.html @@ -1,13 +1,13 @@ - + dependency-check-core - Tag List report @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -175,16 +175,16 @@
  • - + - PMD + CPD Report
  • - + - CPD + PMD Report
  • @@ -247,34 +247,40 @@ Tag strings used by tag class Todo Work -18 +20 todo, FIXME

    Each tag is detailed below:

    Todo Work

    -

    Number of occurrences found in the code: 18

    +

    Number of occurrences found in the code: 20

    - - - - + + + + + + + - + - + + + + - + - + @@ -286,37 +292,43 @@ - + - + - - + + - + - + - + - + - - + + - + + + + + + + - + diff --git a/dependency-check-core/team-list.html b/dependency-check-core/team-list.html index 2f3b470b4..fad3e9b7c 100644 --- a/dependency-check-core/team-list.html +++ b/dependency-check-core/team-list.html @@ -1,13 +1,13 @@ - + dependency-check-core - Team list @@ -54,7 +54,7 @@
  • - + /
  • @@ -67,9 +67,9 @@ -
  • | Last Published: 2015-05-11
  • +
  • | Last Published: 2015-08-04
  • - Version: 1.2.11 + Version: 1.3.0
  • @@ -223,6 +223,13 @@ + + + + + + +
    org.owasp.dependencycheck.analyzer.ArchiveAnalyzer Line
    add nupkg, apk, sar?108
    - can we get more evidence from the parent? EAR contains module name, etc. analyze the dependency (i.e. extract files) if it is a supported type.230
    238
    org.owasp.dependencycheck.analyzer.CMakeAnalyzerLine
    - refactor so we do not assign to the parameter (checkstyle)193
    org.owasp.dependencycheck.analyzer.CPEAnalyzer Line
    test dojo-war against this. we shold get dojo-toolkit:dojo-toolkit AND dojo-toolkit:toolkit177
    179
    - 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.409
    - likely need to change the split... not sure if this will work for CPE with special chars425
    427
    the following isn't quite right is it? need to think about this guessing game a bit more.529
    531
    org.owasp.dependencycheck.analyzer.DependencyBundlingAnalyzerTest Line
    Line
    fix the version problem below166
    174
    - 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).267
    275
    move this startsWith expression to a configuration file?276
    move this startsWith expression to the base suppression file284
    move this to the hint analyzer364
    381
    org.owasp.dependencycheck.analyzer.JarAnalyzer Line
    remove weighting600
    604
    change this to a regex?718
    728
    org.owasp.dependencycheck.analyzer.JavaScriptAnalyzerTestorg.owasp.dependencycheck.data.nvdcve.ConnectionFactory Line
    improve the assertions assertTrue(depJQ6.getEvidence().size() > 0); assertTrue(depJQ10.getEvidence().size() > 0); assertTrue(depJQ10min.getEvidence().size() > 0);106
    convert this to use DatabaseProperties343
    org.owasp.dependencycheck.data.update.StandardUpdateIntegrationTestorg.owasp.dependencycheck.data.update.CpeUpdaterLine
    - move this to a util class as it is duplicative of (copy of) code in the DownloadTask155
    org.owasp.dependencycheck.data.update.NvdCveUpdaterIntegrationTest Line
    make this an actual test }56
    47
    org.owasp.dependencycheck.dependency.EvidenceCollection Line
    Will.Stranathan@owasp.org OWASP https://www.owasp.org/developer
    Dale Visserdvisser@ida.orgInstitute for Defense Analyseshttps://www.ida.org/ developer

    Contributors

    diff --git a/dependency-check-core/xref-test/allclasses-frame.html b/dependency-check-core/xref-test/allclasses-frame.html index 09a04234d..3f77682ce 100644 --- a/dependency-check-core/xref-test/allclasses-frame.html +++ b/dependency-check-core/xref-test/allclasses-frame.html @@ -31,18 +31,33 @@
  • AssemblyAnalyzerTest +
  • +
  • + AutoconfAnalyzerTest
  • BaseDBTestCase
  • BaseTest +
  • +
  • + BaseUpdaterImpl +
  • +
  • + BaseUpdaterTest +
  • +
  • + CMakeAnalyzerTest
  • CPEAnalyzerIntegrationTest
  • CentralSearchTest +
  • +
  • + CpeUpdaterIntegrationTest
  • CveDBIntegrationTest @@ -58,6 +73,9 @@
  • DateUtilTest +
  • +
  • + DependencyBundlingAnalyzerIntegrationTest
  • DependencyBundlingAnalyzerTest @@ -72,7 +90,7 @@ DependencyVersionUtilTest
  • - DownloadTaskTest + DownloadTaskTest
  • DriverLoaderTest @@ -106,9 +124,6 @@
  • JarAnalyzerTest -
  • -
  • - JavaScriptAnalyzerTest
  • LuceneUtilsTest @@ -123,16 +138,19 @@ NuspecAnalyzerTest
  • - NvdCveInfoTest + NvdCveInfoTest
  • NvdCveUpdaterIntegrationTest
  • - NvdCve_1_2_HandlerTest + NvdCve_1_2_HandlerTest
  • - NvdCve_2_0_HandlerTest + NvdCve_2_0_HandlerTest +
  • +
  • + OpenSSLAnalyzerTest
  • PomUtilsTest @@ -148,9 +166,6 @@
  • ReportGeneratorIntegrationTest -
  • -
  • - StandardUpdateIntegrationTest
  • SuppressionHandlerTest @@ -165,7 +180,7 @@ TokenPairConcatenatingFilterTest
  • - UpdateableNvdCveTest + UpdateableNvdCveTest
  • UrlTokenizingFilterTest diff --git a/dependency-check-core/xref-test/index.html b/dependency-check-core/xref-test/index.html index 197fb6e15..a5edb35ba 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.2.11 Reference + Dependency-Check Core 1.3.0 Reference 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 238709395..aaa6b2ef0 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/BaseTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/BaseTest.html @@ -43,36 +43,45 @@ 35 36 @AfterClass 37 public static void tearDownClass() throws Exception { -38 Settings.cleanup(true); -39 } -40 -41 /** -42 * Returns the given resource as an InputStream using the object's class loader. The org.junit.Assume API is used so that test -43 * cases are skipped if the resource is not available. -44 * -45 * @param o the object used to obtain a reference to the class loader -46 * @param resource the name of the resource to load -47 * @return the resource as an InputStream -48 */ -49 public static InputStream getResourceAsStream(Object o, String resource) { -50 getResourceAsFile(o, resource); -51 return o.getClass().getClassLoader().getResourceAsStream(resource); -52 } -53 -54 /** -55 * Returns the given resource as a File using the object's class loader. The org.junit.Assume API is used so that test cases -56 * are skipped if the resource is not available. -57 * -58 * @param o the object used to obtain a reference to the class loader -59 * @param resource the name of the resource to load -60 * @return the resource as an File -61 */ -62 public static File getResourceAsFile(Object o, String resource) { -63 File f = new File(o.getClass().getClassLoader().getResource(resource).getPath()); -64 Assume.assumeTrue(String.format("%n%n[SEVERE] Unable to load resource for test case: %s%n%n", resource), f.exists()); -65 return f; -66 } -67 } +38 File f = new File("./target/data/dc.h2.db"); +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"); +43 System.err.println("------------------------------------------------"); +44 System.err.println("------------------------------------------------"); +45 } +46 +47 Settings.cleanup(true); +48 } +49 +50 /** +51 * Returns the given resource as an InputStream using the object's class loader. The org.junit.Assume API is used so that test +52 * cases are skipped if the resource is not available. +53 * +54 * @param o the object used to obtain a reference to the class loader +55 * @param resource the name of the resource to load +56 * @return the resource as an InputStream +57 */ +58 public static InputStream getResourceAsStream(Object o, String resource) { +59 getResourceAsFile(o, resource); +60 return o.getClass().getClassLoader().getResourceAsStream(resource); +61 } +62 +63 /** +64 * Returns the given resource as a File using the object's class loader. The org.junit.Assume API is used so that test cases +65 * are skipped if the resource is not available. +66 * +67 * @param o the object used to obtain a reference to the class loader +68 * @param resource the name of the resource to load +69 * @return the resource as an File +70 */ +71 public static File getResourceAsFile(Object o, String resource) { +72 File f = new File(o.getClass().getClassLoader().getResource(resource).getPath()); +73 Assume.assumeTrue(String.format("%n%n[SEVERE] Unable to load resource for test case: %s%n%n", resource), f.exists()); +74 return f; +75 } +76 }
    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 11058669c..f40548520 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 @@ -34,98 +34,97 @@ 26 import org.owasp.dependencycheck.suppression.SuppressionParseException; 27 import org.owasp.dependencycheck.suppression.SuppressionRule; 28 import org.owasp.dependencycheck.utils.Settings; -29 -30 import java.net.MalformedURLException; -31 import java.net.URISyntaxException; -32 import java.util.List; -33 import java.util.Set; -34 import java.util.logging.Level; -35 import java.util.logging.Logger; -36 -37 import static org.junit.Assert.assertNull; -38 import static org.junit.Assert.assertTrue; -39 -40 /** -41 * @author Jeremy Long -42 */ -43 public class AbstractSuppressionAnalyzerTest extends BaseTest { -44 -45 private AbstractSuppressionAnalyzer instance; -46 -47 @Before -48 public void createObjectUnderTest() throws Exception { -49 instance = new AbstractSuppressionAnalyzerImpl(); -50 } -51 -52 /** -53 * Test of getSupportedExtensions method, of class AbstractSuppressionAnalyzer. -54 */ -55 @Test -56 public void testGetSupportedExtensions() { -57 Set<String> result = instance.getSupportedExtensions(); -58 assertNull(result); -59 } -60 -61 /** -62 * Test of getRules method, of class AbstractSuppressionAnalyzer for suppression file declared as URL. -63 */ -64 @Test -65 public void testGetRulesFromSuppressionFileFromURL() throws Exception { -66 setSupressionFileFromURL(); -67 instance.initialize(); -68 int expCount = 5; -69 List<SuppressionRule> result = instance.getRules(); -70 assertTrue(expCount <= result.size()); -71 } -72 -73 /** -74 * Test of getRules method, of class AbstractSuppressionAnalyzer for suppression file declared as URL. -75 */ -76 @Test -77 public void testGetRulesFromSuppressionFileInClasspath() throws Exception { -78 Settings.setString(Settings.KEYS.SUPPRESSION_FILE, "suppressions.xml"); -79 instance.initialize(); -80 int expCount = 5; -81 List<SuppressionRule> result = instance.getRules(); -82 assertTrue(expCount <= result.size()); -83 } -84 -85 @Test(expected = SuppressionParseException.class) -86 public void testFailureToLocateSuppressionFileAnywhere() throws Exception { -87 Settings.setString(Settings.KEYS.SUPPRESSION_FILE, "doesnotexist.xml"); -88 instance.initialize(); -89 } -90 -91 private void setSupressionFileFromURL() throws Exception { -92 try { -93 final String uri = this.getClass().getClassLoader().getResource("suppressions.xml").toURI().toURL().toString(); -94 Settings.setString(Settings.KEYS.SUPPRESSION_FILE, uri); -95 } catch (URISyntaxException ex) { -96 Logger.getLogger(AbstractSuppressionAnalyzerTest.class.getName()).log(Level.SEVERE, null, ex); -97 } catch (MalformedURLException ex) { -98 Logger.getLogger(AbstractSuppressionAnalyzerTest.class.getName()).log(Level.SEVERE, null, ex); -99 } -100 } -101 -102 public class AbstractSuppressionAnalyzerImpl extends AbstractSuppressionAnalyzer { -103 -104 @Override -105 public void analyze(Dependency dependency, Engine engine) throws AnalysisException { -106 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. -107 } -108 -109 @Override -110 public String getName() { -111 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. -112 } -113 -114 @Override -115 public AnalysisPhase getAnalysisPhase() { -116 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. -117 } -118 } -119 -120 } +29 import org.slf4j.LoggerFactory; +30 +31 import java.net.MalformedURLException; +32 import java.net.URISyntaxException; +33 import java.util.List; +34 import java.util.Set; +35 +36 import static org.junit.Assert.assertNull; +37 import static org.junit.Assert.assertTrue; +38 +39 /** +40 * @author Jeremy Long +41 */ +42 public class AbstractSuppressionAnalyzerTest extends BaseTest { +43 +44 private AbstractSuppressionAnalyzer instance; +45 +46 @Before +47 public void createObjectUnderTest() throws Exception { +48 instance = new AbstractSuppressionAnalyzerImpl(); +49 } +50 +51 /** +52 * Test of getSupportedExtensions method, of class AbstractSuppressionAnalyzer. +53 */ +54 @Test +55 public void testGetSupportedExtensions() { +56 Set<String> result = instance.getSupportedExtensions(); +57 assertNull(result); +58 } +59 +60 /** +61 * Test of getRules method, of class AbstractSuppressionAnalyzer for suppression file declared as URL. +62 */ +63 @Test +64 public void testGetRulesFromSuppressionFileFromURL() throws Exception { +65 setSupressionFileFromURL(); +66 instance.initialize(); +67 int expCount = 5; +68 List<SuppressionRule> result = instance.getRules(); +69 assertTrue(expCount <= result.size()); +70 } +71 +72 /** +73 * Test of getRules method, of class AbstractSuppressionAnalyzer for suppression file declared as URL. +74 */ +75 @Test +76 public void testGetRulesFromSuppressionFileInClasspath() throws Exception { +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()); +82 } +83 +84 @Test(expected = SuppressionParseException.class) +85 public void testFailureToLocateSuppressionFileAnywhere() throws Exception { +86 Settings.setString(Settings.KEYS.SUPPRESSION_FILE, "doesnotexist.xml"); +87 instance.initialize(); +88 } +89 +90 private void setSupressionFileFromURL() throws Exception { +91 try { +92 final String uri = this.getClass().getClassLoader().getResource("suppressions.xml").toURI().toURL().toString(); +93 Settings.setString(Settings.KEYS.SUPPRESSION_FILE, uri); +94 } catch (URISyntaxException ex) { +95 LoggerFactory.getLogger(AbstractSuppressionAnalyzerTest.class).error("", ex); +96 } catch (MalformedURLException ex) { +97 LoggerFactory.getLogger(AbstractSuppressionAnalyzerTest.class).error("", ex); +98 } +99 } +100 +101 public class AbstractSuppressionAnalyzerImpl extends AbstractSuppressionAnalyzer { +102 +103 @Override +104 public void analyze(Dependency dependency, Engine engine) throws AnalysisException { +105 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. +106 } +107 +108 @Override +109 public String getName() { +110 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. +111 } +112 +113 @Override +114 public AnalysisPhase getAnalysisPhase() { +115 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. +116 } +117 } +118 +119 }
    diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/ArchiveAnalyzerIntegrationTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/ArchiveAnalyzerIntegrationTest.html index 04fe852cc..6b84ed976 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/ArchiveAnalyzerIntegrationTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/ArchiveAnalyzerIntegrationTest.html @@ -28,40 +28,40 @@ 20 import java.io.File; 21 import java.util.HashSet; 22 import java.util.Set; -23 import static org.junit.Assert.assertEquals; -24 import static org.junit.Assert.assertTrue; -25 import org.junit.Test; -26 import org.owasp.dependencycheck.BaseTest; -27 import org.owasp.dependencycheck.Engine; -28 import org.owasp.dependencycheck.data.cpe.AbstractDatabaseTestCase; -29 import org.owasp.dependencycheck.dependency.Dependency; -30 import org.owasp.dependencycheck.utils.Settings; -31 -32 /** -33 * -34 * @author Jeremy Long -35 */ -36 public class ArchiveAnalyzerIntegrationTest extends AbstractDatabaseTestCase { -37 -38 /** -39 * Test of getSupportedExtensions method, of class ArchiveAnalyzer. -40 */ -41 @Test -42 public void testGetSupportedExtensions() { -43 ArchiveAnalyzer instance = new ArchiveAnalyzer(); -44 Set<String> expResult = new HashSet<String>(); -45 expResult.add("zip"); -46 expResult.add("war"); -47 expResult.add("ear"); -48 expResult.add("jar"); -49 expResult.add("sar"); -50 expResult.add("apk"); -51 expResult.add("nupkg"); -52 expResult.add("tar"); -53 expResult.add("gz"); -54 expResult.add("tgz"); -55 Set result = instance.getSupportedExtensions(); -56 assertEquals(expResult, result); +23 import static org.junit.Assert.*; +24 import org.junit.Test; +25 import org.owasp.dependencycheck.BaseTest; +26 import org.owasp.dependencycheck.Engine; +27 import org.owasp.dependencycheck.data.cpe.AbstractDatabaseTestCase; +28 import org.owasp.dependencycheck.dependency.Dependency; +29 import org.owasp.dependencycheck.utils.Settings; +30 +31 /** +32 * +33 * @author Jeremy Long +34 */ +35 public class ArchiveAnalyzerIntegrationTest extends AbstractDatabaseTestCase { +36 +37 /** +38 * Test of getSupportedExtensions method, of class ArchiveAnalyzer. +39 */ +40 @Test +41 public void testSupportsExtensions() { +42 ArchiveAnalyzer instance = new ArchiveAnalyzer(); +43 Set<String> expResult = new HashSet<String>(); +44 expResult.add("zip"); +45 expResult.add("war"); +46 expResult.add("ear"); +47 expResult.add("jar"); +48 expResult.add("sar"); +49 expResult.add("apk"); +50 expResult.add("nupkg"); +51 expResult.add("tar"); +52 expResult.add("gz"); +53 expResult.add("tgz"); +54 for (String ext : expResult) { +55 assertTrue(ext, instance.accept(new File("test." + ext))); +56 } 57 } 58 59 /** @@ -80,231 +80,214 @@ 72 */ 73 @Test 74 public void testSupportsExtension() { -75 String extension = "7z"; //not supported +75 String extension = "test.7z"; //not supported 76 ArchiveAnalyzer instance = new ArchiveAnalyzer(); -77 boolean expResult = false; -78 boolean result = instance.supportsExtension(extension); -79 assertEquals(expResult, result); -80 -81 extension = "war"; //supported -82 expResult = true; -83 result = instance.supportsExtension(extension); -84 assertEquals(expResult, result); -85 -86 extension = "ear"; //supported -87 result = instance.supportsExtension(extension); +77 assertFalse(extension, instance.accept(new File(extension))); +78 } +79 +80 /** +81 * Test of getAnalysisPhase method, of class ArchiveAnalyzer. +82 */ +83 @Test +84 public void testGetAnalysisPhase() { +85 ArchiveAnalyzer instance = new ArchiveAnalyzer(); +86 AnalysisPhase expResult = AnalysisPhase.INITIAL; +87 AnalysisPhase result = instance.getAnalysisPhase(); 88 assertEquals(expResult, result); -89 -90 extension = "zip"; //supported -91 result = instance.supportsExtension(extension); -92 assertEquals(expResult, result); -93 -94 extension = "nupkg"; //supported -95 result = instance.supportsExtension(extension); -96 assertEquals(expResult, result); -97 } -98 -99 /** -100 * Test of getAnalysisPhase method, of class ArchiveAnalyzer. -101 */ -102 @Test -103 public void testGetAnalysisPhase() { -104 ArchiveAnalyzer instance = new ArchiveAnalyzer(); -105 AnalysisPhase expResult = AnalysisPhase.INITIAL; -106 AnalysisPhase result = instance.getAnalysisPhase(); -107 assertEquals(expResult, result); -108 } -109 -110 /** -111 * Test of initialize and close methods, of class ArchiveAnalyzer. -112 */ -113 @Test -114 public void testInitialize() throws Exception { -115 ArchiveAnalyzer instance = new ArchiveAnalyzer(); -116 instance.initialize(); -117 -118 instance.close(); -119 -120 //no exception means things worked. -121 } -122 -123 /** -124 * Test of analyze method, of class ArchiveAnalyzer. -125 */ -126 @Test -127 public void testAnalyze() throws Exception { -128 ArchiveAnalyzer instance = new ArchiveAnalyzer(); -129 //trick the analyzer into thinking it is active. -130 instance.supportsExtension("ear"); -131 try { -132 instance.initialize(); -133 File file = BaseTest.getResourceAsFile(this, "daytrader-ear-2.1.7.ear"); -134 //File file = new File(this.getClass().getClassLoader().getResource("daytrader-ear-2.1.7.ear").getPath()); -135 Dependency dependency = new Dependency(file); -136 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); -137 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); -138 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); -139 Engine engine = new Engine(); -140 -141 int initial_size = engine.getDependencies().size(); -142 instance.analyze(dependency, engine); -143 int ending_size = engine.getDependencies().size(); -144 -145 engine.cleanup(); -146 -147 assertTrue(initial_size < ending_size); -148 -149 } finally { -150 instance.close(); -151 } -152 } -153 -154 /** -155 * Test of analyze method, of class ArchiveAnalyzer. -156 */ -157 @Test -158 public void testAnalyzeTar() throws Exception { -159 ArchiveAnalyzer instance = new ArchiveAnalyzer(); -160 //trick the analyzer into thinking it is active so that it will initialize -161 instance.supportsExtension("tar"); -162 try { -163 instance.initialize(); -164 -165 //File file = new File(this.getClass().getClassLoader().getResource("file.tar").getPath()); -166 //File file = new File(this.getClass().getClassLoader().getResource("stagedhttp-modified.tar").getPath()); -167 File file = BaseTest.getResourceAsFile(this, "stagedhttp-modified.tar"); -168 Dependency dependency = new Dependency(file); -169 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); -170 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); -171 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); -172 Engine engine = new Engine(); -173 -174 int initial_size = engine.getDependencies().size(); -175 instance.analyze(dependency, engine); -176 int ending_size = engine.getDependencies().size(); -177 engine.cleanup(); +89 } +90 +91 /** +92 * Test of initialize and close methods, of class ArchiveAnalyzer. +93 */ +94 @Test +95 public void testInitialize() throws Exception { +96 ArchiveAnalyzer instance = new ArchiveAnalyzer(); +97 instance.setEnabled(true); +98 instance.setFilesMatched(true); +99 instance.initialize(); +100 +101 instance.close(); +102 +103 //no exception means things worked. +104 } +105 +106 /** +107 * Test of analyze method, of class ArchiveAnalyzer. +108 */ +109 @Test +110 public void testAnalyze() throws Exception { +111 ArchiveAnalyzer instance = new ArchiveAnalyzer(); +112 //trick the analyzer into thinking it is active. +113 instance.accept(new File("test.ear")); +114 try { +115 instance.initialize(); +116 File file = BaseTest.getResourceAsFile(this, "daytrader-ear-2.1.7.ear"); +117 //File file = new File(this.getClass().getClassLoader().getResource("daytrader-ear-2.1.7.ear").getPath()); +118 Dependency dependency = new Dependency(file); +119 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); +120 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); +121 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); +122 Engine engine = new Engine(); +123 +124 int initial_size = engine.getDependencies().size(); +125 instance.analyze(dependency, engine); +126 int ending_size = engine.getDependencies().size(); +127 +128 engine.cleanup(); +129 +130 assertTrue(initial_size < ending_size); +131 +132 } finally { +133 instance.close(); +134 } +135 } +136 +137 /** +138 * Test of analyze method, of class ArchiveAnalyzer. +139 */ +140 @Test +141 public void testAnalyzeTar() throws Exception { +142 ArchiveAnalyzer instance = new ArchiveAnalyzer(); +143 //trick the analyzer into thinking it is active so that it will initialize +144 instance.accept(new File("test.tar")); +145 try { +146 instance.initialize(); +147 +148 //File file = new File(this.getClass().getClassLoader().getResource("file.tar").getPath()); +149 //File file = new File(this.getClass().getClassLoader().getResource("stagedhttp-modified.tar").getPath()); +150 File file = BaseTest.getResourceAsFile(this, "stagedhttp-modified.tar"); +151 Dependency dependency = new Dependency(file); +152 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); +153 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); +154 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); +155 Engine engine = new Engine(); +156 +157 int initial_size = engine.getDependencies().size(); +158 instance.analyze(dependency, engine); +159 int ending_size = engine.getDependencies().size(); +160 engine.cleanup(); +161 +162 assertTrue(initial_size < ending_size); +163 +164 } finally { +165 instance.close(); +166 } +167 } +168 +169 /** +170 * Test of analyze method, of class ArchiveAnalyzer. +171 */ +172 @Test +173 public void testAnalyzeTarGz() throws Exception { +174 ArchiveAnalyzer instance = new ArchiveAnalyzer(); +175 instance.accept(new File("zip")); //ensure analyzer is "enabled" +176 try { +177 instance.initialize(); 178 -179 assertTrue(initial_size < ending_size); -180 -181 } finally { -182 instance.close(); -183 } -184 } -185 -186 /** -187 * Test of analyze method, of class ArchiveAnalyzer. -188 */ -189 @Test -190 public void testAnalyzeTarGz() throws Exception { -191 ArchiveAnalyzer instance = new ArchiveAnalyzer(); -192 instance.supportsExtension("zip"); //ensure analyzer is "enabled" -193 try { -194 instance.initialize(); -195 -196 //File file = new File(this.getClass().getClassLoader().getResource("file.tar.gz").getPath()); -197 File file = BaseTest.getResourceAsFile(this, "file.tar.gz"); -198 //Dependency dependency = new Dependency(file); -199 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); -200 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); -201 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); -202 Engine engine = new Engine(); -203 -204 int initial_size = engine.getDependencies().size(); -205 //instance.analyze(dependency, engine); -206 engine.scan(file); -207 engine.analyzeDependencies(); -208 int ending_size = engine.getDependencies().size(); -209 engine.cleanup(); -210 assertTrue(initial_size < ending_size); -211 -212 } finally { -213 instance.close(); -214 } -215 } -216 -217 // /** -218 // * Test of analyze method, of class ArchiveAnalyzer. -219 // */ -220 // @Test -221 // public void testNestedZipFolder() throws Exception { -222 // ArchiveAnalyzer instance = new ArchiveAnalyzer(); -223 // try { -224 // instance.initialize(); -225 // -226 // File file = new File(this.getClass().getClassLoader().getResource("nested.zip").getPath()); -227 // Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); -228 // Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); -229 // Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); -230 // Engine engine = new Engine(); -231 // -232 // engine.scan(file); -233 // engine.analyzeDependencies(); -234 // -235 // } finally { -236 // instance.close(); -237 // } -238 // } -239 /** -240 * Test of analyze method, of class ArchiveAnalyzer. -241 */ -242 @Test -243 public void testAnalyzeTgz() throws Exception { -244 ArchiveAnalyzer instance = new ArchiveAnalyzer(); -245 instance.supportsExtension("zip"); //ensure analyzer is "enabled" -246 try { -247 instance.initialize(); -248 -249 //File file = new File(this.getClass().getClassLoader().getResource("file.tgz").getPath()); -250 File file = BaseTest.getResourceAsFile(this, "file.tgz"); -251 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); -252 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); -253 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); -254 Engine engine = new Engine(); -255 -256 int initial_size = engine.getDependencies().size(); -257 engine.scan(file); -258 engine.analyzeDependencies(); -259 int ending_size = engine.getDependencies().size(); -260 engine.cleanup(); -261 assertTrue(initial_size < ending_size); -262 -263 } finally { -264 instance.close(); -265 } -266 } -267 -268 /** -269 * Test of analyze method, of class ArchiveAnalyzer. -270 */ -271 @Test -272 public void testAnalyze_badZip() throws Exception { -273 ArchiveAnalyzer instance = new ArchiveAnalyzer(); -274 try { -275 instance.initialize(); -276 -277 //File file = new File(this.getClass().getClassLoader().getResource("test.zip").getPath()); -278 File file = BaseTest.getResourceAsFile(this, "test.zip"); -279 Dependency dependency = new Dependency(file); -280 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); -281 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); -282 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); -283 Engine engine = new Engine(); -284 int initial_size = engine.getDependencies().size(); -285 // boolean failed = false; -286 // try { -287 instance.analyze(dependency, engine); -288 // } catch (java.lang.UnsupportedClassVersionError ex) { -289 // failed = true; -290 // } -291 // assertTrue(failed); -292 int ending_size = engine.getDependencies().size(); -293 engine.cleanup(); -294 assertEquals(initial_size, ending_size); -295 } finally { -296 instance.close(); -297 } -298 } -299 } +179 //File file = new File(this.getClass().getClassLoader().getResource("file.tar.gz").getPath()); +180 File file = BaseTest.getResourceAsFile(this, "file.tar.gz"); +181 //Dependency dependency = new Dependency(file); +182 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); +183 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); +184 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); +185 Engine engine = new Engine(); +186 +187 int initial_size = engine.getDependencies().size(); +188 //instance.analyze(dependency, engine); +189 engine.scan(file); +190 engine.analyzeDependencies(); +191 int ending_size = engine.getDependencies().size(); +192 engine.cleanup(); +193 assertTrue(initial_size < ending_size); +194 +195 } finally { +196 instance.close(); +197 } +198 } +199 +200 // /** +201 // * Test of analyze method, of class ArchiveAnalyzer. +202 // */ +203 // @Test +204 // public void testNestedZipFolder() throws Exception { +205 // ArchiveAnalyzer instance = new ArchiveAnalyzer(); +206 // try { +207 // instance.initialize(); +208 // +209 // File file = new File(this.getClass().getClassLoader().getResource("nested.zip").getPath()); +210 // Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); +211 // Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); +212 // Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); +213 // Engine engine = new Engine(); +214 // +215 // engine.scan(file); +216 // engine.analyzeDependencies(); +217 // +218 // } finally { +219 // instance.close(); +220 // } +221 // } +222 /** +223 * Test of analyze method, of class ArchiveAnalyzer. +224 */ +225 @Test +226 public void testAnalyzeTgz() throws Exception { +227 ArchiveAnalyzer instance = new ArchiveAnalyzer(); +228 instance.accept(new File("zip")); //ensure analyzer is "enabled" +229 try { +230 instance.initialize(); +231 +232 //File file = new File(this.getClass().getClassLoader().getResource("file.tgz").getPath()); +233 File file = BaseTest.getResourceAsFile(this, "file.tgz"); +234 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); +235 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); +236 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); +237 Engine engine = new Engine(); +238 +239 int initial_size = engine.getDependencies().size(); +240 engine.scan(file); +241 engine.analyzeDependencies(); +242 int ending_size = engine.getDependencies().size(); +243 engine.cleanup(); +244 assertTrue(initial_size < ending_size); +245 +246 } finally { +247 instance.close(); +248 } +249 } +250 +251 /** +252 * Test of analyze method, of class ArchiveAnalyzer. +253 */ +254 @Test +255 public void testAnalyze_badZip() throws Exception { +256 ArchiveAnalyzer instance = new ArchiveAnalyzer(); +257 try { +258 instance.initialize(); +259 +260 //File file = new File(this.getClass().getClassLoader().getResource("test.zip").getPath()); +261 File file = BaseTest.getResourceAsFile(this, "test.zip"); +262 Dependency dependency = new Dependency(file); +263 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false); +264 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); +265 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); +266 Engine engine = new Engine(); +267 int initial_size = engine.getDependencies().size(); +268 // boolean failed = false; +269 // try { +270 instance.analyze(dependency, engine); +271 // } catch (java.lang.UnsupportedClassVersionError ex) { +272 // failed = true; +273 // } +274 // assertTrue(failed); +275 int ending_size = engine.getDependencies().size(); +276 engine.cleanup(); +277 assertEquals(initial_size, ending_size); +278 } finally { +279 instance.close(); +280 } +281 } +282 }
    diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/AssemblyAnalyzerTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/AssemblyAnalyzerTest.html index ad745f4e1..c447dc5ec 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/AssemblyAnalyzerTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/AssemblyAnalyzerTest.html @@ -26,22 +26,22 @@ 18 package org.owasp.dependencycheck.analyzer; 19 20 import java.io.File; -21 import java.util.logging.Level; -22 import java.util.logging.Logger; -23 import org.junit.After; -24 import static org.junit.Assert.assertEquals; -25 import static org.junit.Assert.assertTrue; -26 import static org.junit.Assert.fail; -27 import org.junit.Assume; -28 import static org.junit.Assume.assumeFalse; -29 import org.junit.Before; -30 import org.junit.Test; -31 import org.owasp.dependencycheck.BaseTest; -32 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; -33 import org.owasp.dependencycheck.dependency.Confidence; -34 import org.owasp.dependencycheck.dependency.Dependency; -35 import org.owasp.dependencycheck.dependency.Evidence; -36 import org.owasp.dependencycheck.utils.Settings; +21 import org.junit.After; +22 import static org.junit.Assert.assertEquals; +23 import static org.junit.Assert.assertTrue; +24 import static org.junit.Assert.fail; +25 import org.junit.Assume; +26 import static org.junit.Assume.assumeFalse; +27 import org.junit.Before; +28 import org.junit.Test; +29 import org.owasp.dependencycheck.BaseTest; +30 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; +31 import org.owasp.dependencycheck.dependency.Confidence; +32 import org.owasp.dependencycheck.dependency.Dependency; +33 import org.owasp.dependencycheck.dependency.Evidence; +34 import org.owasp.dependencycheck.utils.Settings; +35 import org.slf4j.Logger; +36 import org.slf4j.LoggerFactory; 37 38 /** 39 * Tests for the AssemblyAnalyzer. @@ -51,143 +51,141 @@ 43 */ 44 public class AssemblyAnalyzerTest extends BaseTest { 45 -46 private static final Logger LOGGER = Logger.getLogger(AssemblyAnalyzerTest.class.getName()); +46 private static final Logger LOGGER = LoggerFactory.getLogger(AssemblyAnalyzerTest.class); 47 -48 AssemblyAnalyzer analyzer; +48 private static final String LOG_KEY = "org.slf4j.simpleLogger.org.owasp.dependencycheck.analyzer.AssemblyAnalyzer"; 49 -50 /** -51 * Sets up the analyzer. -52 * -53 * @throws Exception if anything goes sideways -54 */ -55 @Before -56 public void setUp() throws Exception { -57 try { -58 analyzer = new AssemblyAnalyzer(); -59 analyzer.supportsExtension("dll"); -60 analyzer.initialize(); -61 } catch (Exception e) { -62 if (e.getMessage().contains("Could not execute .NET AssemblyAnalyzer")) { -63 LOGGER.log(Level.WARNING, "Exception setting up AssemblyAnalyzer. Tests will be incomplete"); -64 } else { -65 LOGGER.log(Level.WARNING, "Exception setting up AssemblyAnalyzer. Tests will be incomplete", e); -66 } -67 Assume.assumeNoException("Is mono installed? TESTS WILL BE INCOMPLETE", e); -68 } -69 } -70 -71 /** -72 * Tests to make sure the name is correct. -73 */ -74 @Test -75 public void testGetName() { -76 assertEquals("Assembly Analyzer", analyzer.getName()); -77 } -78 -79 @Test -80 public void testAnalysis() throws Exception { -81 //File f = new File(AssemblyAnalyzerTest.class.getClassLoader().getResource("GrokAssembly.exe").getPath()); -82 File f = BaseTest.getResourceAsFile(this, "GrokAssembly.exe"); -83 Dependency d = new Dependency(f); -84 analyzer.analyze(d, null); -85 boolean foundVendor = false; -86 for (Evidence e : d.getVendorEvidence().getEvidence("grokassembly", "vendor")) { -87 if ("OWASP".equals(e.getValue())) { -88 foundVendor = true; -89 } -90 } -91 assertTrue(foundVendor); -92 -93 boolean foundProduct = false; -94 for (Evidence e : d.getProductEvidence().getEvidence("grokassembly", "product")) { -95 if ("GrokAssembly".equals(e.getValue())) { -96 foundProduct = true; -97 } -98 } -99 assertTrue(foundProduct); -100 } -101 -102 @Test -103 public void testLog4Net() throws Exception { -104 //File f = new File(AssemblyAnalyzerTest.class.getClassLoader().getResource("log4net.dll").getPath()); -105 File f = BaseTest.getResourceAsFile(this, "log4net.dll"); -106 -107 Dependency d = new Dependency(f); -108 analyzer.analyze(d, null); -109 assertTrue(d.getVersionEvidence().getEvidence().contains(new Evidence("grokassembly", "version", "1.2.13.0", Confidence.HIGHEST))); -110 assertTrue(d.getVendorEvidence().getEvidence().contains(new Evidence("grokassembly", "vendor", "The Apache Software Foundation", Confidence.HIGH))); -111 assertTrue(d.getProductEvidence().getEvidence().contains(new Evidence("grokassembly", "product", "log4net", Confidence.HIGH))); -112 } -113 -114 @Test -115 public void testNonexistent() { -116 Level oldLevel = Logger.getLogger(AssemblyAnalyzer.class.getName()).getLevel(); -117 Level oldDependency = Logger.getLogger(Dependency.class.getName()).getLevel(); +50 AssemblyAnalyzer analyzer; +51 +52 /** +53 * Sets up the analyzer. +54 * +55 * @throws Exception if anything goes sideways +56 */ +57 @Before +58 public void setUp() throws Exception { +59 try { +60 analyzer = new AssemblyAnalyzer(); +61 analyzer.accept(new File("test.dll")); // trick into "thinking it is active" +62 analyzer.initialize(); +63 } catch (Exception e) { +64 if (e.getMessage().contains("Could not execute .NET AssemblyAnalyzer")) { +65 LOGGER.warn("Exception setting up AssemblyAnalyzer. Tests will be incomplete"); +66 } else { +67 LOGGER.warn("Exception setting up AssemblyAnalyzer. Tests will be incomplete", e); +68 } +69 Assume.assumeNoException("Is mono installed? TESTS WILL BE INCOMPLETE", e); +70 } +71 } +72 +73 /** +74 * Tests to make sure the name is correct. +75 */ +76 @Test +77 public void testGetName() { +78 assertEquals("Assembly Analyzer", analyzer.getName()); +79 } +80 +81 @Test +82 public void testAnalysis() throws Exception { +83 //File f = new File(AssemblyAnalyzerTest.class.getClassLoader().getResource("GrokAssembly.exe").getPath()); +84 File f = BaseTest.getResourceAsFile(this, "GrokAssembly.exe"); +85 Dependency d = new Dependency(f); +86 analyzer.analyze(d, null); +87 boolean foundVendor = false; +88 for (Evidence e : d.getVendorEvidence().getEvidence("grokassembly", "vendor")) { +89 if ("OWASP".equals(e.getValue())) { +90 foundVendor = true; +91 } +92 } +93 assertTrue(foundVendor); +94 +95 boolean foundProduct = false; +96 for (Evidence e : d.getProductEvidence().getEvidence("grokassembly", "product")) { +97 if ("GrokAssembly".equals(e.getValue())) { +98 foundProduct = true; +99 } +100 } +101 assertTrue(foundProduct); +102 } +103 +104 @Test +105 public void testLog4Net() throws Exception { +106 //File f = new File(AssemblyAnalyzerTest.class.getClassLoader().getResource("log4net.dll").getPath()); +107 File f = BaseTest.getResourceAsFile(this, "log4net.dll"); +108 +109 Dependency d = new Dependency(f); +110 analyzer.analyze(d, null); +111 assertTrue(d.getVersionEvidence().getEvidence().contains(new Evidence("grokassembly", "version", "1.2.13.0", Confidence.HIGHEST))); +112 assertTrue(d.getVendorEvidence().getEvidence().contains(new Evidence("grokassembly", "vendor", "The Apache Software Foundation", Confidence.HIGH))); +113 assertTrue(d.getProductEvidence().getEvidence().contains(new Evidence("grokassembly", "product", "log4net", Confidence.HIGH))); +114 } +115 +116 @Test +117 public void testNonexistent() { 118 // Tweak the log level so the warning doesn't show in the console -119 Logger.getLogger(AssemblyAnalyzer.class.getName()).setLevel(Level.OFF); -120 Logger.getLogger(Dependency.class.getName()).setLevel(Level.OFF); -121 //File f = new File(AssemblyAnalyzerTest.class.getClassLoader().getResource("log4net.dll").getPath()); -122 File f = BaseTest.getResourceAsFile(this, "log4net.dll"); -123 File test = new File(f.getParent(), "nonexistent.dll"); -124 Dependency d = new Dependency(test); -125 -126 try { -127 analyzer.analyze(d, null); -128 fail("Expected an AnalysisException"); -129 } catch (AnalysisException ae) { -130 assertEquals("File does not exist", ae.getMessage()); -131 } finally { -132 Logger.getLogger(AssemblyAnalyzer.class.getName()).setLevel(oldLevel); -133 Logger.getLogger(Dependency.class.getName()).setLevel(oldDependency); -134 } -135 } -136 -137 @Test -138 public void testWithSettingMono() throws Exception { -139 -140 //This test doesn't work on Windows. -141 assumeFalse(System.getProperty("os.name").startsWith("Windows")); -142 -143 String oldValue = Settings.getString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH); -144 // if oldValue is null, that means that neither the system property nor the setting has -145 // been set. If that's the case, then we have to make it such that when we recover, -146 // null still comes back. But you can't put a null value in a HashMap, so we have to set -147 // the system property rather than the setting. -148 if (oldValue == null) { -149 System.setProperty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, "/yooser/bine/mono"); -150 } else { -151 Settings.setString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, "/yooser/bine/mono"); -152 } -153 -154 Level oldLevel = Logger.getLogger(AssemblyAnalyzer.class.getName()).getLevel(); -155 try { -156 // Tweak the logging to swallow the warning when testing -157 Logger.getLogger(AssemblyAnalyzer.class.getName()).setLevel(Level.OFF); -158 // Have to make a NEW analyzer because during setUp, it would have gotten the correct one -159 AssemblyAnalyzer aanalyzer = new AssemblyAnalyzer(); -160 aanalyzer.supportsExtension("dll"); -161 aanalyzer.initialize(); -162 fail("Expected an AnalysisException"); -163 } catch (AnalysisException ae) { -164 assertEquals("An error occured with the .NET AssemblyAnalyzer", ae.getMessage()); -165 } finally { -166 // Recover the logger -167 Logger.getLogger(AssemblyAnalyzer.class.getName()).setLevel(oldLevel); -168 // Now recover the way we came in. If we had to set a System property, delete it. Otherwise, -169 // reset the old value -170 if (oldValue == null) { -171 System.getProperties().remove(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH); -172 } else { -173 Settings.setString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, oldValue); -174 } -175 } -176 } -177 -178 @After -179 public void tearDown() throws Exception { -180 analyzer.close(); -181 } -182 } +119 String oldProp = System.getProperty(LOG_KEY, "info"); +120 //File f = new File(AssemblyAnalyzerTest.class.getClassLoader().getResource("log4net.dll").getPath()); +121 File f = BaseTest.getResourceAsFile(this, "log4net.dll"); +122 File test = new File(f.getParent(), "nonexistent.dll"); +123 Dependency d = new Dependency(test); +124 +125 try { +126 analyzer.analyze(d, null); +127 fail("Expected an AnalysisException"); +128 } catch (AnalysisException ae) { +129 assertEquals("File does not exist", ae.getMessage()); +130 } finally { +131 System.setProperty(LOG_KEY, oldProp); +132 } +133 } +134 +135 @Test +136 public void testWithSettingMono() throws Exception { +137 +138 //This test doesn't work on Windows. +139 assumeFalse(System.getProperty("os.name").startsWith("Windows")); +140 +141 String oldValue = Settings.getString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH); +142 // if oldValue is null, that means that neither the system property nor the setting has +143 // been set. If that's the case, then we have to make it such that when we recover, +144 // null still comes back. But you can't put a null value in a HashMap, so we have to set +145 // the system property rather than the setting. +146 if (oldValue == null) { +147 System.setProperty(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, "/yooser/bine/mono"); +148 } else { +149 Settings.setString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, "/yooser/bine/mono"); +150 } +151 +152 String oldProp = System.getProperty(LOG_KEY, "info"); +153 try { +154 // Tweak the logging to swallow the warning when testing +155 System.setProperty(LOG_KEY, "error"); +156 // Have to make a NEW analyzer because during setUp, it would have gotten the correct one +157 AssemblyAnalyzer aanalyzer = new AssemblyAnalyzer(); +158 aanalyzer.accept(new File("test.dll")); // trick into "thinking it is active" +159 aanalyzer.initialize(); +160 fail("Expected an AnalysisException"); +161 } catch (AnalysisException ae) { +162 assertEquals("An error occured with the .NET AssemblyAnalyzer", ae.getMessage()); +163 } finally { +164 System.setProperty(LOG_KEY, oldProp); +165 // Recover the logger +166 // Now recover the way we came in. If we had to set a System property, delete it. Otherwise, +167 // reset the old value +168 if (oldValue == null) { +169 System.getProperties().remove(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH); +170 } else { +171 Settings.setString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, oldValue); +172 } +173 } +174 } +175 +176 @After +177 public void tearDown() throws Exception { +178 analyzer.close(); +179 } +180 }
    diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/AutoconfAnalyzerTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/AutoconfAnalyzerTest.html new file mode 100644 index 000000000..ee77a33bd --- /dev/null +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/AutoconfAnalyzerTest.html @@ -0,0 +1,189 @@ + + + +AutoconfAnalyzerTest 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) 2015 Institute for Defense Analyses. 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.junit.Assert.assertEquals;
    +30  import static org.junit.Assert.assertTrue;
    +31  
    +32  /**
    +33   * Unit tests for AutoconfAnalyzer. The test resources under autoconf/ were
    +34   * obtained from outside open source software projects. Links to those projects
    +35   * are given below.
    +36   *
    +37   * @author Dale Visser <dvisser@ida.org>
    +38   * @see <a href="http://readable.sourceforge.net/">Readable Lisp S-expressions
    +39   *      Project</a>
    +40   * @see <a href="https://gnu.org/software/binutils/">GNU Binutils</a>
    +41   * @see <a href="https://gnu.org/software/ghostscript/">GNU Ghostscript</a>
    +42   */
    +43  public class AutoconfAnalyzerTest extends BaseTest {
    +44  
    +45  	/**
    +46  	 * The analyzer to test.
    +47  	 */
    +48  	AutoconfAnalyzer analyzer;
    +49  
    +50  	private void assertCommonEvidence(Dependency result, String product,
    +51  			String version, String vendor) {
    +52  		assertProductAndVersion(result, product, version);
    +53  		assertTrue("Expected vendor evidence to contain \"" + vendor + "\".",
    +54  				result.getVendorEvidence().toString().contains(vendor));
    +55  	}
    +56  
    +57  	private void assertProductAndVersion(Dependency result, String product,
    +58  			String version) {
    +59  		assertTrue("Expected product evidence to contain \"" + product + "\".",
    +60  				result.getProductEvidence().toString().contains(product));
    +61  		assertTrue("Expected version evidence to contain \"" + version + "\".",
    +62  				result.getVersionEvidence().toString().contains(version));
    +63  	}
    +64  
    +65  	/**
    +66  	 * Correctly setup the analyzer for testing.
    +67  	 *
    +68  	 * @throws Exception
    +69  	 *             thrown if there is a problem
    +70  	 */
    +71  	@Before
    +72  	public void setUp() throws Exception {
    +73  		analyzer = new AutoconfAnalyzer();
    +74  		analyzer.setFilesMatched(true);
    +75  		analyzer.initialize();
    +76  	}
    +77  
    +78  	/**
    +79  	 * Cleanup the analyzer's temp files, etc.
    +80  	 *
    +81  	 * @throws Exception
    +82  	 *             thrown if there is a problem
    +83  	 */
    +84  	@After
    +85  	public void tearDown() throws Exception {
    +86  		analyzer.close();
    +87  		analyzer = null;
    +88  	}
    +89  
    +90  	/**
    +91  	 * Test whether expected evidence is gathered from Ghostscript's
    +92  	 * configure.ac.
    +93  	 *
    +94  	 * @throws AnalysisException
    +95  	 *             is thrown when an exception occurs.
    +96  	 */
    +97  	@Test
    +98  	public void testAnalyzeConfigureAC1() throws AnalysisException {
    +99  		final Dependency result = new Dependency(BaseTest.getResourceAsFile(
    +100 				this, "autoconf/ghostscript/configure.ac"));
    +101 		analyzer.analyze(result, null);
    +102 		assertCommonEvidence(result, "ghostscript", "8.62.0", "gnu");
    +103 	}
    +104 
    +105 	/**
    +106 	 * Test whether expected evidence is gathered from Readable's configure.ac.
    +107 	 *
    +108 	 * @throws AnalysisException
    +109 	 *             is thrown when an exception occurs.
    +110 	 */
    +111 	@Test
    +112 	public void testAnalyzeConfigureAC2() throws AnalysisException {
    +113 		final Dependency result = new Dependency(BaseTest.getResourceAsFile(
    +114 				this, "autoconf/readable-code/configure.ac"));
    +115 		analyzer.analyze(result, null);
    +116 		assertReadableCodeEvidence(result);
    +117 	}
    +118 
    +119 	private void assertReadableCodeEvidence(final Dependency result) {
    +120 		assertCommonEvidence(result, "readable", "1.0.7", "dwheeler");
    +121 		final String url = "http://readable.sourceforge.net/";
    +122 		assertTrue("Expected product evidence to contain \"" + url + "\".",
    +123 				result.getVendorEvidence().toString().contains(url));
    +124 	}
    +125 
    +126 	/**
    +127 	 * Test whether expected evidence is gathered from GNU Binutil's configure.
    +128 	 *
    +129 	 * @throws AnalysisException
    +130 	 *             is thrown when an exception occurs.
    +131 	 */
    +132 	@Test
    +133 	public void testAnalyzeConfigureScript() throws AnalysisException {
    +134 		final Dependency result = new Dependency(BaseTest.getResourceAsFile(
    +135 				this, "autoconf/binutils/configure"));
    +136 		analyzer.analyze(result, null);
    +137 		assertProductAndVersion(result, "binutils", "2.25.51");
    +138 	}
    +139 
    +140 	/**
    +141 	 * Test whether expected evidence is gathered from GNU Ghostscript's
    +142 	 * configure.
    +143 	 *
    +144 	 * @throws AnalysisException
    +145 	 *             is thrown when an exception occurs.
    +146 	 */
    +147 	@Test
    +148 	public void testAnalyzeReadableConfigureScript() throws AnalysisException {
    +149 		final Dependency result = new Dependency(BaseTest.getResourceAsFile(
    +150 				this, "autoconf/readable-code/configure"));
    +151 		analyzer.analyze(result, null);
    +152 		assertReadableCodeEvidence(result);
    +153 	}
    +154 
    +155 	/**
    +156 	 * Test of getName method, of {@link AutoconfAnalyzer}.
    +157 	 */
    +158 	@Test
    +159 	public void testGetName() {
    +160 		assertEquals("Analyzer name wrong.", "Autoconf Analyzer",
    +161 				analyzer.getName());
    +162 	}
    +163 
    +164 	/**
    +165 	 * Test of {@link AutoconfAnalyzer#accept(File)}.
    +166 	 */
    +167 	@Test
    +168 	public void testSupportsFileExtension() {
    +169 		assertTrue("Should support \"ac\" extension.",
    +170 				analyzer.accept(new File("configure.ac")));
    +171 		assertTrue("Should support \"in\" extension.",
    +172 				analyzer.accept(new File("configure.in")));
    +173 		assertTrue("Should support \"configure\" extension.",
    +174 				analyzer.accept(new File("configure")));
    +175 	}
    +176 }
    +
    +
    + + + diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/CMakeAnalyzerTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/CMakeAnalyzerTest.html new file mode 100644 index 000000000..964ec5142 --- /dev/null +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/CMakeAnalyzerTest.html @@ -0,0 +1,165 @@ + + + +CMakeAnalyzerTest 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) 2015 Institute for Defense Analyses. 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.Engine;
    +25  import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
    +26  import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
    +27  import org.owasp.dependencycheck.dependency.Dependency;
    +28  
    +29  import java.io.File;
    +30  import java.util.List;
    +31  import java.util.regex.Pattern;
    +32  
    +33  import static org.hamcrest.CoreMatchers.equalTo;
    +34  import static org.hamcrest.CoreMatchers.is;
    +35  import static org.junit.Assert.*;
    +36  import org.owasp.dependencycheck.data.nvdcve.BaseDBTestCase;
    +37  
    +38  /**
    +39   * Unit tests for CmakeAnalyzer.
    +40   *
    +41   * @author Dale Visser <dvisser@ida.org>
    +42   */
    +43  public class CMakeAnalyzerTest extends BaseDBTestCase {
    +44  
    +45      /**
    +46       * The package analyzer to test.
    +47       */
    +48      CMakeAnalyzer analyzer;
    +49  
    +50      /**
    +51       * Setup the CmakeAnalyzer.
    +52       *
    +53       * @throws Exception if there is a problem
    +54       */
    +55      @Before
    +56      public void setUp() throws Exception {
    +57          super.setUp();
    +58          analyzer = new CMakeAnalyzer();
    +59          analyzer.setFilesMatched(true);
    +60          analyzer.initialize();
    +61      }
    +62  
    +63      /**
    +64       * Cleanup any resources used.
    +65       *
    +66       * @throws Exception 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 PythonPackageAnalyzer.
    +76       */
    +77      @Test
    +78      public void testGetName() {
    +79          assertThat(analyzer.getName(), is(equalTo("CMake Analyzer")));
    +80      }
    +81  
    +82      /**
    +83       * Test of supportsExtension method, of class PythonPackageAnalyzer.
    +84       */
    +85      @Test
    +86      public void testAccept() {
    +87          assertTrue("Should support \"CMakeLists.txt\" name.",
    +88                  analyzer.accept(new File("CMakeLists.txt")));
    +89          assertTrue("Should support \"cmake\" extension.",
    +90                  analyzer.accept(new File("test.cmake")));
    +91      }
    +92  
    +93      /**
    +94       * Test whether expected evidence is gathered from OpenCV's CMakeLists.txt.
    +95       *
    +96       * @throws AnalysisException is thrown when an exception occurs.
    +97       */
    +98      @Test
    +99      public void testAnalyzeCMakeListsOpenCV() throws AnalysisException {
    +100         final Dependency result = new Dependency(BaseTest.getResourceAsFile(
    +101                 this, "cmake/opencv/CMakeLists.txt"));
    +102         analyzer.analyze(result, null);
    +103         final String product = "OpenCV";
    +104         assertProductEvidence(result, product);
    +105     }
    +106 
    +107     /**
    +108      * Test whether expected evidence is gathered from OpenCV's CMakeLists.txt.
    +109      *
    +110      * @throws AnalysisException is thrown when an exception occurs.
    +111      */
    +112     @Test
    +113     public void testAnalyzeCMakeListsZlib() throws AnalysisException {
    +114         final Dependency result = new Dependency(BaseTest.getResourceAsFile(
    +115                 this, "cmake/zlib/CMakeLists.txt"));
    +116         analyzer.analyze(result, null);
    +117         final String product = "zlib";
    +118         assertProductEvidence(result, product);
    +119     }
    +120 
    +121     private void assertProductEvidence(Dependency result, String product) {
    +122         assertTrue("Expected product evidence to contain \"" + product + "\".",
    +123                 result.getProductEvidence().toString().contains(product));
    +124     }
    +125 
    +126     /**
    +127      * Test whether expected version evidence is gathered from OpenCV's third party cmake files.
    +128      *
    +129      * @throws AnalysisException is thrown when an exception occurs.
    +130      */
    +131     @Test
    +132     public void testAnalyzeCMakeListsOpenCV3rdParty() throws AnalysisException, DatabaseException {
    +133         final Dependency result = new Dependency(BaseTest.getResourceAsFile(
    +134                 this, "cmake/opencv/3rdparty/ffmpeg/ffmpeg_version.cmake"));
    +135         final Engine engine = new Engine();
    +136         analyzer.analyze(result, engine);
    +137         assertProductEvidence(result, "libavcodec");
    +138         assertVersionEvidence(result, "55.18.102");
    +139         assertFalse("ALIASOF_ prefix shouldn't be present.",
    +140                 Pattern.compile("\\bALIASOF_\\w+").matcher(result.getProductEvidence().toString()).find());
    +141         final List<Dependency> dependencies = engine.getDependencies();
    +142         assertEquals("Number of additional dependencies should be 4.", 4, dependencies.size());
    +143         final Dependency last = dependencies.get(3);
    +144         assertProductEvidence(last, "libavresample");
    +145         assertVersionEvidence(last, "1.0.1");
    +146     }
    +147 
    +148     private void assertVersionEvidence(Dependency result, String version) {
    +149         assertTrue("Expected version evidence to contain \"" + version + "\".",
    +150                 result.getVersionEvidence().toString().contains(version));
    +151     }
    +152 }
    +
    +
    + + + 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 ecb0b1c65..bf929759c 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 @@ -102,9 +102,9 @@ 94 try { 95 //callDetermineCPE_full("struts2-core-2.3.16.3.jar", "cpe:/a:apache:struts:2.3.16.3", instance, fnAnalyzer, jarAnalyzer, hAnalyzer, fp); 96 callDetermineCPE_full("hazelcast-2.5.jar", null, instance, fnAnalyzer, jarAnalyzer, hAnalyzer, fp); -97 callDetermineCPE_full("spring-context-support-2.5.5.jar", "cpe:/a:vmware:springsource_spring_framework:2.5.5", instance, fnAnalyzer, jarAnalyzer, hAnalyzer, fp); +97 callDetermineCPE_full("spring-context-support-2.5.5.jar", "cpe:/a:springsource:spring_framework:2.5.5", instance, fnAnalyzer, jarAnalyzer, hAnalyzer, fp); 98 callDetermineCPE_full("spring-core-3.0.0.RELEASE.jar", "cpe:/a:vmware:springsource_spring_framework:3.0.0", instance, fnAnalyzer, jarAnalyzer, hAnalyzer, fp); -99 callDetermineCPE_full("org.mortbay.jetty.jar", "cpe:/a:mortbay_jetty:jetty:4.2", instance, fnAnalyzer, jarAnalyzer, hAnalyzer, fp); +99 callDetermineCPE_full("org.mortbay.jetty.jar", "cpe:/a:mortbay_jetty:jetty:4.2.27", instance, fnAnalyzer, jarAnalyzer, hAnalyzer, fp); 100 callDetermineCPE_full("jaxb-xercesImpl-1.5.jar", null, instance, fnAnalyzer, jarAnalyzer, hAnalyzer, fp); 101 callDetermineCPE_full("ehcache-core-2.2.0.jar", null, instance, fnAnalyzer, jarAnalyzer, hAnalyzer, fp); 102 } finally { @@ -155,110 +155,117 @@ 147 FileNameAnalyzer fnAnalyzer = new FileNameAnalyzer(); 148 fnAnalyzer.analyze(struts, null); 149 -150 JarAnalyzer jarAnalyzer = new JarAnalyzer(); -151 jarAnalyzer.analyze(struts, null); -152 -153 //File fileCommonValidator = new File(this.getClass().getClassLoader().getResource("commons-validator-1.4.0.jar").getPath()); -154 File fileCommonValidator = BaseTest.getResourceAsFile(this, "commons-validator-1.4.0.jar"); -155 Dependency commonValidator = new Dependency(fileCommonValidator); -156 jarAnalyzer.analyze(commonValidator, null); -157 -158 //File fileSpring = new File(this.getClass().getClassLoader().getResource("spring-core-2.5.5.jar").getPath()); -159 File fileSpring = BaseTest.getResourceAsFile(this, "spring-core-2.5.5.jar"); -160 Dependency spring = new Dependency(fileSpring); -161 jarAnalyzer.analyze(spring, null); -162 -163 //File fileSpring3 = new File(this.getClass().getClassLoader().getResource("spring-core-3.0.0.RELEASE.jar").getPath()); -164 File fileSpring3 = BaseTest.getResourceAsFile(this, "spring-core-3.0.0.RELEASE.jar"); -165 Dependency spring3 = new Dependency(fileSpring3); -166 jarAnalyzer.analyze(spring3, null); +150 HintAnalyzer hintAnalyzer = new HintAnalyzer(); +151 JarAnalyzer jarAnalyzer = new JarAnalyzer(); +152 jarAnalyzer.accept(new File("test.jar"));//trick analyzer into "thinking it is active" +153 +154 jarAnalyzer.analyze(struts, null); +155 hintAnalyzer.analyze(struts, null); +156 //File fileCommonValidator = new File(this.getClass().getClassLoader().getResource("commons-validator-1.4.0.jar").getPath()); +157 File fileCommonValidator = BaseTest.getResourceAsFile(this, "commons-validator-1.4.0.jar"); +158 Dependency commonValidator = new Dependency(fileCommonValidator); +159 jarAnalyzer.analyze(commonValidator, null); +160 hintAnalyzer.analyze(commonValidator, null); +161 +162 //File fileSpring = new File(this.getClass().getClassLoader().getResource("spring-core-2.5.5.jar").getPath()); +163 File fileSpring = BaseTest.getResourceAsFile(this, "spring-core-2.5.5.jar"); +164 Dependency spring = new Dependency(fileSpring); +165 jarAnalyzer.analyze(spring, null); +166 hintAnalyzer.analyze(spring, null); 167 -168 CPEAnalyzer instance = new CPEAnalyzer(); -169 instance.open(); -170 instance.determineCPE(commonValidator); -171 instance.determineCPE(struts); -172 instance.determineCPE(spring); -173 instance.determineCPE(spring3); -174 instance.close(); -175 -176 String expResult = "cpe:/a:apache:struts:2.1.2"; -177 Identifier expIdentifier = new Identifier("cpe", expResult, expResult); -178 String expResultSpring = "cpe:/a:springsource:spring_framework:2.5.5"; -179 String expResultSpring3 = "cpe:/a:vmware:springsource_spring_framework:3.0.0"; -180 -181 for (Identifier i : commonValidator.getIdentifiers()) { -182 Assert.assertFalse("Apache Common Validator - found a CPE identifier?", "cpe".equals(i.getType())); -183 } -184 -185 Assert.assertTrue("Incorrect match size - struts", struts.getIdentifiers().size() >= 1); -186 Assert.assertTrue("Incorrect match - struts", struts.getIdentifiers().contains(expIdentifier)); -187 Assert.assertTrue("Incorrect match size - spring3 - " + spring3.getIdentifiers().size(), spring3.getIdentifiers().size() >= 1); -188 -189 //the following two only work if the HintAnalyzer is used. -190 //Assert.assertTrue("Incorrect match size - spring", spring.getIdentifiers().size() == 1); -191 //Assert.assertTrue("Incorrect match - spring", spring.getIdentifiers().get(0).getValue().equals(expResultSpring)); -192 } -193 -194 /** -195 * Test of determineIdentifiers method, of class CPEAnalyzer. -196 * -197 * @throws Exception is thrown when an exception occurs -198 */ -199 @Test -200 public void testDetermineIdentifiers() throws Exception { -201 Dependency openssl = new Dependency(); -202 openssl.getVendorEvidence().addEvidence("test", "vendor", "openssl", Confidence.HIGHEST); -203 openssl.getProductEvidence().addEvidence("test", "product", "openssl", Confidence.HIGHEST); -204 openssl.getVersionEvidence().addEvidence("test", "version", "1.0.1c", Confidence.HIGHEST); -205 -206 CPEAnalyzer instance = new CPEAnalyzer(); -207 instance.open(); -208 instance.determineIdentifiers(openssl, "openssl", "openssl", Confidence.HIGHEST); -209 instance.close(); -210 -211 String expResult = "cpe:/a:openssl:openssl:1.0.1c"; -212 Identifier expIdentifier = new Identifier("cpe", expResult, expResult); -213 -214 assertTrue(openssl.getIdentifiers().contains(expIdentifier)); -215 -216 } +168 //File fileSpring3 = new File(this.getClass().getClassLoader().getResource("spring-core-3.0.0.RELEASE.jar").getPath()); +169 File fileSpring3 = BaseTest.getResourceAsFile(this, "spring-core-3.0.0.RELEASE.jar"); +170 Dependency spring3 = new Dependency(fileSpring3); +171 jarAnalyzer.analyze(spring3, null); +172 hintAnalyzer.analyze(spring3, null); +173 +174 CPEAnalyzer instance = new CPEAnalyzer(); +175 instance.open(); +176 instance.determineCPE(commonValidator); +177 instance.determineCPE(struts); +178 instance.determineCPE(spring); +179 instance.determineCPE(spring3); +180 instance.close(); +181 +182 String expResult = "cpe:/a:apache:struts:2.1.2"; +183 Identifier expIdentifier = new Identifier("cpe", expResult, expResult); +184 String expResultSpring = "cpe:/a:springsource:spring_framework:2.5.5"; +185 String expResultSpring3 = "cpe:/a:vmware:springsource_spring_framework:3.0.0"; +186 +187 for (Identifier i : commonValidator.getIdentifiers()) { +188 Assert.assertFalse("Apache Common Validator - found a CPE identifier?", "cpe".equals(i.getType())); +189 } +190 +191 Assert.assertTrue("Incorrect match size - struts", struts.getIdentifiers().size() >= 1); +192 Assert.assertTrue("Incorrect match - struts", struts.getIdentifiers().contains(expIdentifier)); +193 Assert.assertTrue("Incorrect match size - spring3 - " + spring3.getIdentifiers().size(), spring3.getIdentifiers().size() >= 1); +194 +195 //the following two only work if the HintAnalyzer is used. +196 //Assert.assertTrue("Incorrect match size - spring", spring.getIdentifiers().size() == 1); +197 //Assert.assertTrue("Incorrect match - spring", spring.getIdentifiers().get(0).getValue().equals(expResultSpring)); +198 jarAnalyzer.close(); +199 } +200 +201 /** +202 * Test of determineIdentifiers method, of class CPEAnalyzer. +203 * +204 * @throws Exception is thrown when an exception occurs +205 */ +206 @Test +207 public void testDetermineIdentifiers() throws Exception { +208 Dependency openssl = new Dependency(); +209 openssl.getVendorEvidence().addEvidence("test", "vendor", "openssl", Confidence.HIGHEST); +210 openssl.getProductEvidence().addEvidence("test", "product", "openssl", Confidence.HIGHEST); +211 openssl.getVersionEvidence().addEvidence("test", "version", "1.0.1c", Confidence.HIGHEST); +212 +213 CPEAnalyzer instance = new CPEAnalyzer(); +214 instance.open(); +215 instance.determineIdentifiers(openssl, "openssl", "openssl", Confidence.HIGHEST); +216 instance.close(); 217 -218 /** -219 * Test of searchCPE method, of class CPEAnalyzer. -220 * -221 * @throws Exception is thrown when an exception occurs -222 */ -223 @Test -224 public void testSearchCPE() throws Exception { -225 String vendor = "apache software foundation"; -226 String product = "struts 2 core"; -227 String version = "2.1.2"; -228 String expVendor = "apache"; -229 String expProduct = "struts"; -230 -231 CPEAnalyzer instance = new CPEAnalyzer(); -232 instance.open(); -233 -234 Set<String> productWeightings = new HashSet<String>(1); -235 productWeightings.add("struts2"); -236 -237 Set<String> vendorWeightings = new HashSet<String>(1); -238 vendorWeightings.add("apache"); -239 -240 List<IndexEntry> result = instance.searchCPE(vendor, product, productWeightings, vendorWeightings); -241 instance.close(); -242 -243 boolean found = false; -244 for (IndexEntry entry : result) { -245 if (expVendor.equals(entry.getVendor()) && expProduct.equals(entry.getProduct())) { -246 found = true; -247 break; -248 } -249 } -250 assertTrue("apache:struts was not identified", found); -251 -252 } -253 } +218 String expResult = "cpe:/a:openssl:openssl:1.0.1c"; +219 Identifier expIdentifier = new Identifier("cpe", expResult, expResult); +220 +221 assertTrue(openssl.getIdentifiers().contains(expIdentifier)); +222 +223 } +224 +225 /** +226 * Test of searchCPE method, of class CPEAnalyzer. +227 * +228 * @throws Exception is thrown when an exception occurs +229 */ +230 @Test +231 public void testSearchCPE() throws Exception { +232 String vendor = "apache software foundation"; +233 String product = "struts 2 core"; +234 String version = "2.1.2"; +235 String expVendor = "apache"; +236 String expProduct = "struts"; +237 +238 CPEAnalyzer instance = new CPEAnalyzer(); +239 instance.open(); +240 +241 Set<String> productWeightings = new HashSet<String>(1); +242 productWeightings.add("struts2"); +243 +244 Set<String> vendorWeightings = new HashSet<String>(1); +245 vendorWeightings.add("apache"); +246 +247 List<IndexEntry> result = instance.searchCPE(vendor, product, productWeightings, vendorWeightings); +248 instance.close(); +249 +250 boolean found = false; +251 for (IndexEntry entry : result) { +252 if (expVendor.equals(entry.getVendor()) && expProduct.equals(entry.getProduct())) { +253 found = true; +254 break; +255 } +256 } +257 assertTrue("apache:struts was not identified", found); +258 +259 } +260 }
    diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzerIntegrationTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzerIntegrationTest.html new file mode 100644 index 000000000..fc8bc6b46 --- /dev/null +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzerIntegrationTest.html @@ -0,0 +1,118 @@ + + + +DependencyBundlingAnalyzerIntegrationTest 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) 2015 Jeremy Long. All Rights Reserved.
    +17   */
    +18  package org.owasp.dependencycheck.analyzer;
    +19  
    +20  import java.io.File;
    +21  import static org.junit.Assert.assertEquals;
    +22  import org.junit.Test;
    +23  import org.owasp.dependencycheck.BaseTest;
    +24  import org.owasp.dependencycheck.Engine;
    +25  import org.owasp.dependencycheck.data.cpe.AbstractDatabaseTestCase;
    +26  import org.owasp.dependencycheck.dependency.Dependency;
    +27  import org.owasp.dependencycheck.utils.Settings;
    +28  
    +29  /**
    +30   *
    +31   * @author Jeremy Long
    +32   */
    +33  public class DependencyBundlingAnalyzerIntegrationTest extends AbstractDatabaseTestCase {
    +34  
    +35      /**
    +36       * Test of analyze method, of class DependencyBundlingAnalyzer.
    +37       */
    +38      @Test
    +39      public void testAnalyze() throws Exception {
    +40  //        Engine engine = null;
    +41  //        JarAnalyzer ja = null;
    +42  //        FileNameAnalyzer fna = null;
    +43  //        CPEAnalyzer cpea = null;
    +44  //        DependencyBundlingAnalyzer instance = null;
    +45  //        try {
    +46  //            //Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false);
    +47  //            Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false);
    +48  //            //Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false);
    +49  //            engine = new Engine();
    +50  //            engine.doUpdates();
    +51  //
    +52  //            File file1 = new File("C:\\Users\\jeremy\\Projects\\testCases\\batlik\\app1.war");
    +53  //            File file2 = new File("C:\\Users\\jeremy\\Projects\\testCases\\batlik\\app2.war");
    +54  //            Dependency dependency1 = new Dependency(file1);
    +55  //            Dependency dependency2 = new Dependency(file2);
    +56  //            engine.getDependencies().add(dependency1);
    +57  //            engine.getDependencies().add(dependency2);
    +58  //            ArchiveAnalyzer aa = new ArchiveAnalyzer();
    +59  //            aa.setEnabled(true);
    +60  //            aa.setFilesMatched(true);
    +61  //            aa.initialize();
    +62  //            ja = new JarAnalyzer();
    +63  //            ja.setFilesMatched(true);
    +64  //            ja.setEnabled(true);
    +65  //            ja.initialize();
    +66  //            fna = new FileNameAnalyzer();
    +67  //            fna.initialize();
    +68  //            cpea = new CPEAnalyzer();
    +69  //            cpea.initialize();
    +70  //
    +71  //            aa.analyze(dependency1, engine);
    +72  //            aa.analyze(dependency2, engine);
    +73  //
    +74  //            for (Dependency d : engine.getDependencies()) {
    +75  //                fna.analyze(d, engine);
    +76  //                ja.analyze(d, engine);
    +77  //                cpea.analyze(d, engine);
    +78  //            }
    +79  //
    +80  //            instance = new DependencyBundlingAnalyzer();
    +81  //            instance.initialize();
    +82  //            instance.analyze(null, engine);
    +83  //            System.out.println(engine.getDependencies().size());
    +84  //            for (Dependency d : engine.getDependencies()) {
    +85  //                System.out.println(d.getDisplayFileName());
    +86  //            }
    +87  //        } finally {
    +88  //            if (ja != null) {
    +89  //                ja.close();
    +90  //            }
    +91  //            if (fna != null) {
    +92  //                fna.close();
    +93  //            }
    +94  //            if (cpea != null) {
    +95  //                cpea.close();
    +96  //            }
    +97  //            if (instance != null) {
    +98  //                instance.close();
    +99  //            }
    +100 //            if (engine != null) {
    +101 //                engine.cleanup();
    +102 //            }
    +103 //        }
    +104     }
    +105 }
    +
    +
    + + + diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/HintAnalyzerTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/HintAnalyzerTest.html index 63cde93a4..ee655d18e 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/HintAnalyzerTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/HintAnalyzerTest.html @@ -119,10 +119,9 @@ 111 assertTrue(evidence.contains(springTest3)); 112 //assertTrue(evidence.contains(springTest4)); 113 //assertTrue(evidence.contains(springTest5)); -114 -115 } -116 -117 } +114 } +115 +116 }
    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 b0dd61c37..34c28ba63 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,19 +25,19 @@ 17 */ 18 package org.owasp.dependencycheck.analyzer; 19 -20 import java.io.File; -21 import java.util.HashSet; -22 import java.util.Properties; -23 import java.util.Set; -24 import static org.junit.Assert.assertEquals; -25 import static org.junit.Assert.assertTrue; -26 import org.junit.Test; -27 import org.owasp.dependencycheck.BaseTest; -28 import org.owasp.dependencycheck.dependency.Dependency; -29 import org.owasp.dependencycheck.dependency.Evidence; -30 -31 /** -32 * +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.HashSet; +27 import java.util.Set; +28 +29 import static org.junit.Assert.assertEquals; +30 import static org.junit.Assert.assertTrue; +31 +32 /** 33 * @author Jeremy Long 34 */ 35 public class JarAnalyzerTest extends BaseTest { @@ -102,39 +102,28 @@ 94 * Test of getSupportedExtensions method, of class JarAnalyzer. 95 */ 96 @Test -97 public void testGetSupportedExtensions() { +97 public void testAcceptSupportedExtensions() throws Exception { 98 JarAnalyzer instance = new JarAnalyzer(); -99 Set<String> expResult = new HashSet<String>(); -100 expResult.add("jar"); -101 expResult.add("war"); -102 Set result = instance.getSupportedExtensions(); -103 assertEquals(expResult, result); -104 } -105 -106 /** -107 * Test of getName method, of class JarAnalyzer. -108 */ -109 @Test -110 public void testGetName() { -111 JarAnalyzer instance = new JarAnalyzer(); -112 String expResult = "Jar Analyzer"; -113 String result = instance.getName(); -114 assertEquals(expResult, result); -115 } -116 -117 /** -118 * Test of supportsExtension method, of class JarAnalyzer. -119 */ -120 @Test -121 public void testSupportsExtension() { -122 String extension = "jar"; -123 JarAnalyzer instance = new JarAnalyzer(); -124 boolean expResult = true; -125 boolean result = instance.supportsExtension(extension); -126 assertEquals(expResult, result); -127 } -128 -129 } +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 }
    diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/NuspecAnalyzerTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/NuspecAnalyzerTest.html index 84fa2893b..e39451791 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/NuspecAnalyzerTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/NuspecAnalyzerTest.html @@ -32,40 +32,37 @@ 24 import org.junit.Test; 25 import org.owasp.dependencycheck.BaseTest; 26 -27 public class NuspecAnalyzerTest extends BaseTest { +27 import java.io.File; 28 -29 private NuspecAnalyzer instance; +29 public class NuspecAnalyzerTest extends BaseTest { 30 -31 @Before -32 public void setUp() throws Exception { -33 instance = new NuspecAnalyzer(); -34 instance.setEnabled(true); -35 } -36 -37 @Test -38 public void testGetAnalyzerName() { -39 assertEquals("Nuspec Analyzer", instance.getName()); -40 } -41 -42 @Test -43 public void testGetSupportedExtensions() { -44 assertTrue(instance.getSupportedExtensions().contains("nuspec")); -45 assertFalse(instance.getSupportedExtensions().contains("nupkg")); -46 } -47 -48 @Test -49 public void testSupportsExtension() { -50 assertTrue(instance.supportsExtension("nuspec")); -51 assertFalse(instance.supportsExtension("nupkg")); -52 } -53 -54 @Test -55 public void testGetAnalysisPhaze() { -56 assertEquals(AnalysisPhase.INFORMATION_COLLECTION, instance.getAnalysisPhase()); -57 } -58 } -59 -60 // vim: cc=120:sw=4:ts=4:sts=4 +31 private NuspecAnalyzer instance; +32 +33 @Before +34 public void setUp() throws Exception { +35 instance = new NuspecAnalyzer(); +36 instance.initialize(); +37 instance.setEnabled(true); +38 } +39 +40 @Test +41 public void testGetAnalyzerName() { +42 assertEquals("Nuspec Analyzer", instance.getName()); +43 } +44 +45 @Test +46 public void testSupportsFileExtensions() { +47 assertTrue(instance.accept(new File("test.nuspec"))); +48 assertFalse(instance.accept(new File("test.nupkg"))); +49 } +50 +51 @Test +52 public void testGetAnalysisPhaze() { +53 assertEquals(AnalysisPhase.INFORMATION_COLLECTION, instance.getAnalysisPhase()); +54 } +55 } +56 +57 // vim: cc=120:sw=4:ts=4:sts=4
    diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/OpenSSLAnalyzerTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/OpenSSLAnalyzerTest.html new file mode 100644 index 000000000..e96a47e6e --- /dev/null +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/OpenSSLAnalyzerTest.html @@ -0,0 +1,132 @@ + + + +OpenSSLAnalyzerTest 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) 2015 Institute for Defense Analyses. 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.junit.Assert.*;
    +31  
    +32  /**
    +33   * Unit tests for OpenSSLAnalyzerAnalyzer.
    +34   *
    +35   * @author Dale Visser <dvisser@ida.org>
    +36   */
    +37  public class OpenSSLAnalyzerTest extends BaseTest {
    +38  
    +39      /**
    +40       * The package analyzer to test.
    +41       */
    +42      OpenSSLAnalyzer analyzer;
    +43  
    +44      /**
    +45       * Setup the PtyhonPackageAnalyzer.
    +46       *
    +47       * @throws Exception if there is a problem
    +48       */
    +49      @Before
    +50      public void setUp() throws Exception {
    +51          analyzer = new OpenSSLAnalyzer();
    +52          analyzer.setFilesMatched(true);
    +53          analyzer.initialize();
    +54      }
    +55  
    +56      /**
    +57       * Cleanup any resources used.
    +58       *
    +59       * @throws Exception if there is a problem
    +60       */
    +61      @After
    +62      public void tearDown() throws Exception {
    +63          analyzer.close();
    +64          analyzer = null;
    +65      }
    +66  
    +67      /**
    +68       * Test of getName method, of class OpenSSLAnalyzer.
    +69       */
    +70      @Test
    +71      public void testGetName() {
    +72          assertEquals("Analyzer name wrong.", "OpenSSL Source Analyzer",
    +73                  analyzer.getName());
    +74      }
    +75  
    +76      /**
    +77       * Test of supportsExtension method, of class PythonPackageAnalyzer.
    +78       */
    +79      @Test
    +80      public void testAccept() {
    +81          assertTrue("Should support files named \"opensslv.h\".",
    +82                  analyzer.accept(new File("opensslv.h")));
    +83      }
    +84  
    +85      @Test
    +86      public void testVersionConstantExamples() {
    +87          final long[] constants = {0x1000203fL
    +88                  , 0x00903000
    +89                  , 0x00903001
    +90                  , 0x00903002l
    +91                  , 0x0090300f
    +92                  , 0x0090301f
    +93                  , 0x0090400f
    +94                  , 0x102031af};
    +95          final String[] versions = {"1.0.2c",
    +96                  "0.9.3-dev",
    +97                  "0.9.3-beta1",
    +98                  "0.9.3-beta2",
    +99                  "0.9.3",
    +100                 "0.9.3a",
    +101                 "0.9.4",
    +102                 "1.2.3z"};
    +103         assertEquals(constants.length, versions.length);
    +104         for (int i = 0; i < constants.length; i++) {
    +105             assertEquals(versions[i], OpenSSLAnalyzer.getOpenSSLVersion(constants[i]));
    +106         }
    +107     }
    +108 
    +109     @Test
    +110     public void testOpenSSLVersionHeaderFile() throws AnalysisException {
    +111         final Dependency result = new Dependency(BaseTest.getResourceAsFile(
    +112                 this,
    +113                 "openssl/opensslv.h"));
    +114         analyzer.analyze(result, null);
    +115         assertThat(result.getProductEvidence().toString(), containsString("OpenSSL"));
    +116         assertThat(result.getVendorEvidence().toString(), containsString("OpenSSL"));
    +117         assertThat(result.getVersionEvidence().toString(), containsString("1.0.2c"));
    +118     }
    +119 }
    +
    +
    + + + diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/PythonDistributionAnalyzerTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/PythonDistributionAnalyzerTest.html index 473249d25..434e98e25 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/PythonDistributionAnalyzerTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/PythonDistributionAnalyzerTest.html @@ -25,169 +25,155 @@ 17 */ 18 package org.owasp.dependencycheck.analyzer; 19 -20 import static org.junit.Assert.assertEquals; -21 import static org.junit.Assert.assertTrue; -22 -23 import java.util.Arrays; -24 import java.util.HashSet; -25 -26 import org.apache.commons.lang.StringUtils; -27 import org.junit.After; -28 import org.junit.Before; -29 import org.junit.Test; -30 import org.owasp.dependencycheck.BaseTest; -31 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; -32 import org.owasp.dependencycheck.dependency.Dependency; -33 import org.owasp.dependencycheck.dependency.Evidence; -34 -35 /** -36 * Unit tests for PythonDistributionAnalyzer. -37 * -38 * @author Dale Visser <dvisser@ida.org> -39 */ -40 public class PythonDistributionAnalyzerTest extends BaseTest { -41 -42 /** -43 * The analyzer to test. -44 */ -45 PythonDistributionAnalyzer analyzer; -46 -47 /** -48 * Correctly setup the analyzer for testing. -49 * -50 * @throws Exception thrown if there is a problem -51 */ -52 @Before -53 public void setUp() throws Exception { -54 analyzer = new PythonDistributionAnalyzer(); -55 analyzer.setFilesMatched(true); -56 analyzer.initialize(); -57 } -58 -59 /** -60 * Cleanup the analyzer's temp files, etc. -61 * -62 * @throws Exception thrown if there is a problem -63 */ -64 @After -65 public void tearDown() throws Exception { -66 analyzer.close(); -67 analyzer = null; -68 } -69 -70 /** -71 * Test of getName method, of class PythonDistributionAnalyzer. -72 */ -73 @Test -74 public void testGetName() { -75 assertEquals("Analyzer name wrong.", "Python Distribution Analyzer", -76 analyzer.getName()); -77 } -78 -79 /** -80 * Test of getSupportedExtensions method, of class PythonDistributionAnalyzer. -81 */ -82 @Test -83 public void testGetSupportedExtensions() { -84 final String[] expected = {"whl", "egg", "zip", "METADATA", "PKG-INFO"}; -85 assertEquals("Supported extensions should just have the following: " -86 + StringUtils.join(expected, ", "), -87 new HashSet<String>(Arrays.asList(expected)), -88 analyzer.getSupportedExtensions()); -89 } -90 -91 /** -92 * Test of supportsExtension method, of class PythonDistributionAnalyzer. -93 */ -94 @Test -95 public void testSupportsExtension() { -96 assertTrue("Should support \"whl\" extension.", -97 analyzer.supportsExtension("whl")); -98 assertTrue("Should support \"egg\" extension.", -99 analyzer.supportsExtension("egg")); -100 assertTrue("Should support \"zip\" extension.", -101 analyzer.supportsExtension("zip")); -102 assertTrue("Should support \"METADATA\" extension.", -103 analyzer.supportsExtension("METADATA")); -104 assertTrue("Should support \"PKG-INFO\" extension.", -105 analyzer.supportsExtension("PKG-INFO")); -106 } -107 -108 /** -109 * Test of inspect method, of class PythonDistributionAnalyzer. -110 * -111 * @throws AnalysisException is thrown when an exception occurs. -112 */ -113 @Test -114 public void testAnalyzeWheel() throws AnalysisException { -115 djangoAssertions(new Dependency(BaseTest.getResourceAsFile(this, -116 "python/Django-1.7.2-py2.py3-none-any.whl"))); -117 } -118 -119 /** -120 * Test of inspect method, of class PythonDistributionAnalyzer. -121 * -122 * @throws Exception is thrown when an exception occurs. -123 */ -124 @Test -125 public void testAnalyzeSitePackage() throws AnalysisException { -126 final Dependency result = new Dependency(BaseTest.getResourceAsFile( -127 this, "python/site-packages/Django-1.7.2.dist-info/METADATA")); -128 djangoAssertions(result); -129 assertEquals("Django-1.7.2.dist-info/METADATA", result.getDisplayFileName()); -130 } -131 -132 private void djangoAssertions(final Dependency result) -133 throws AnalysisException { -134 boolean found = false; -135 analyzer.analyze(result, null); -136 assertTrue("Expected vendor evidence to contain \"djangoproject\".", -137 result.getVendorEvidence().toString().contains("djangoproject")); -138 for (final Evidence e : result.getVersionEvidence()) { -139 if ("Version".equals(e.getName()) && "1.7.2".equals(e.getValue())) { -140 found = true; -141 break; -142 } -143 } -144 assertTrue("Version 1.7.2 not found in Django dependency.", found); -145 } -146 -147 @Test -148 public void testAnalyzeEggInfoFolder() throws AnalysisException { -149 eggtestAssertions(this, "python/site-packages/EggTest.egg-info/PKG-INFO"); -150 } -151 -152 @Test -153 public void testAnalyzeEggArchive() throws AnalysisException { -154 eggtestAssertions(this, "python/dist/EggTest-0.0.1-py2.7.egg"); -155 } -156 -157 @Test -158 public void testAnalyzeEggArchiveNamedZip() throws AnalysisException { -159 eggtestAssertions(this, "python/dist/EggTest-0.0.1-py2.7.zip"); -160 } -161 -162 @Test -163 public void testAnalyzeEggFolder() throws AnalysisException { -164 eggtestAssertions(this, "python/site-packages/EggTest-0.0.1-py2.7.egg/EGG-INFO/PKG-INFO"); -165 } -166 -167 public void eggtestAssertions(Object context, final String resource) throws AnalysisException { -168 boolean found = false; -169 final Dependency result = new Dependency(BaseTest.getResourceAsFile( -170 context, resource)); -171 analyzer.analyze(result, null); -172 assertTrue("Expected vendor evidence to contain \"example\".", result -173 .getVendorEvidence().toString().contains("example")); -174 for (final Evidence e : result.getVersionEvidence()) { -175 if ("0.0.1".equals(e.getValue())) { -176 found = true; -177 break; -178 } -179 } -180 assertTrue("Version 0.0.1 not found in EggTest dependency.", found); -181 } -182 } +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 import org.owasp.dependencycheck.dependency.Evidence; +27 +28 import java.io.File; +29 +30 import static org.junit.Assert.assertEquals; +31 import static org.junit.Assert.assertTrue; +32 +33 /** +34 * Unit tests for PythonDistributionAnalyzer. +35 * +36 * @author Dale Visser <dvisser@ida.org> +37 */ +38 public class PythonDistributionAnalyzerTest extends BaseTest { +39 +40 /** +41 * The analyzer to test. +42 */ +43 PythonDistributionAnalyzer 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 PythonDistributionAnalyzer(); +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 of getName method, of class PythonDistributionAnalyzer. +70 */ +71 @Test +72 public void testGetName() { +73 assertEquals("Analyzer name wrong.", "Python Distribution Analyzer", +74 analyzer.getName()); +75 } +76 +77 /** +78 * Test of supportsExtension method, of class PythonDistributionAnalyzer. +79 */ +80 @Test +81 public void testSupportsFiles() { +82 assertTrue("Should support \"whl\" extension.", +83 analyzer.accept(new File("test.whl"))); +84 assertTrue("Should support \"egg\" extension.", +85 analyzer.accept(new File("test.egg"))); +86 assertTrue("Should support \"zip\" extension.", +87 analyzer.accept(new File("test.zip"))); +88 assertTrue("Should support \"METADATA\" extension.", +89 analyzer.accept(new File("METADATA"))); +90 assertTrue("Should support \"PKG-INFO\" extension.", +91 analyzer.accept(new File("PKG-INFO"))); +92 } +93 +94 /** +95 * Test of inspect method, of class PythonDistributionAnalyzer. +96 * +97 * @throws AnalysisException is thrown when an exception occurs. +98 */ +99 @Test +100 public void testAnalyzeWheel() throws AnalysisException { +101 djangoAssertions(new Dependency(BaseTest.getResourceAsFile(this, +102 "python/Django-1.7.2-py2.py3-none-any.whl"))); +103 } +104 +105 /** +106 * Test of inspect method, of class PythonDistributionAnalyzer. +107 * +108 * @throws AnalysisException is thrown when an exception occurs. +109 */ +110 @Test +111 public void testAnalyzeSitePackage() throws AnalysisException { +112 final Dependency result = new Dependency(BaseTest.getResourceAsFile( +113 this, "python/site-packages/Django-1.7.2.dist-info/METADATA")); +114 djangoAssertions(result); +115 assertEquals("Django-1.7.2.dist-info/METADATA", result.getDisplayFileName()); +116 } +117 +118 private void djangoAssertions(final Dependency result) +119 throws AnalysisException { +120 boolean found = false; +121 analyzer.analyze(result, null); +122 assertTrue("Expected vendor evidence to contain \"djangoproject\".", +123 result.getVendorEvidence().toString().contains("djangoproject")); +124 for (final Evidence e : result.getVersionEvidence()) { +125 if ("Version".equals(e.getName()) && "1.7.2".equals(e.getValue())) { +126 found = true; +127 break; +128 } +129 } +130 assertTrue("Version 1.7.2 not found in Django dependency.", found); +131 } +132 +133 @Test +134 public void testAnalyzeEggInfoFolder() throws AnalysisException { +135 eggtestAssertions(this, "python/site-packages/EggTest.egg-info/PKG-INFO"); +136 } +137 +138 @Test +139 public void testAnalyzeEggArchive() throws AnalysisException { +140 eggtestAssertions(this, "python/dist/EggTest-0.0.1-py2.7.egg"); +141 } +142 +143 @Test +144 public void testAnalyzeEggArchiveNamedZip() throws AnalysisException { +145 eggtestAssertions(this, "python/dist/EggTest-0.0.1-py2.7.zip"); +146 } +147 +148 @Test +149 public void testAnalyzeEggFolder() throws AnalysisException { +150 eggtestAssertions(this, "python/site-packages/EggTest-0.0.1-py2.7.egg/EGG-INFO/PKG-INFO"); +151 } +152 +153 public void eggtestAssertions(Object context, final String resource) throws AnalysisException { +154 boolean found = false; +155 final Dependency result = new Dependency(BaseTest.getResourceAsFile( +156 context, resource)); +157 analyzer.analyze(result, null); +158 assertTrue("Expected vendor evidence to contain \"example\".", result +159 .getVendorEvidence().toString().contains("example")); +160 for (final Evidence e : result.getVersionEvidence()) { +161 if ("0.0.1".equals(e.getValue())) { +162 found = true; +163 break; +164 } +165 } +166 assertTrue("Version 0.0.1 not found in EggTest dependency.", found); +167 } +168 }
    diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/PythonPackageAnalyzerTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/PythonPackageAnalyzerTest.html index 991de860d..0ce16e4e6 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/PythonPackageAnalyzerTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/analyzer/PythonPackageAnalyzerTest.html @@ -25,109 +25,94 @@ 17 */ 18 package org.owasp.dependencycheck.analyzer; 19 -20 import static org.junit.Assert.assertEquals; -21 import static org.junit.Assert.assertTrue; -22 -23 import java.util.Arrays; -24 import java.util.HashSet; -25 -26 import org.apache.commons.lang.StringUtils; -27 import org.junit.After; -28 import static org.junit.Assert.assertTrue; -29 import org.junit.Before; -30 import org.junit.Test; -31 import org.owasp.dependencycheck.BaseTest; -32 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; -33 import org.owasp.dependencycheck.dependency.Dependency; -34 import org.owasp.dependencycheck.dependency.Evidence; -35 -36 /** -37 * Unit tests for PythonPackageAnalyzer. -38 * -39 * @author Dale Visser <dvisser@ida.org> -40 */ -41 public class PythonPackageAnalyzerTest extends BaseTest { -42 -43 /** -44 * The package analyzer to test. -45 */ -46 PythonPackageAnalyzer analyzer; -47 -48 /** -49 * Setup the PtyhonPackageAnalyzer. -50 * -51 * @throws Exception if there is a problem -52 */ -53 @Before -54 public void setUp() throws Exception { -55 analyzer = new PythonPackageAnalyzer(); -56 analyzer.setFilesMatched(true); -57 analyzer.initialize(); -58 } -59 -60 /** -61 * Cleanup any resources used. -62 * -63 * @throws Exception if there is a problem -64 */ -65 @After -66 public void tearDown() throws Exception { -67 analyzer.close(); -68 analyzer = null; -69 } -70 -71 /** -72 * Test of getName method, of class PythonPackageAnalyzer. -73 */ -74 @Test -75 public void testGetName() { -76 assertEquals("Analyzer name wrong.", "Python Package Analyzer", -77 analyzer.getName()); -78 } -79 -80 /** -81 * Test of getSupportedExtensions method, of class PythonPackageAnalyzer. -82 */ -83 @Test -84 public void testGetSupportedExtensions() { -85 final String[] expected = {"py"}; -86 assertEquals("Supported extensions should just have the following: " -87 + StringUtils.join(expected, ", "), -88 new HashSet<String>(Arrays.asList(expected)), -89 analyzer.getSupportedExtensions()); +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 import org.owasp.dependencycheck.dependency.Evidence; +27 +28 import java.io.File; +29 +30 import static org.junit.Assert.assertEquals; +31 import static org.junit.Assert.assertTrue; +32 +33 /** +34 * Unit tests for PythonPackageAnalyzer. +35 * +36 * @author Dale Visser <dvisser@ida.org> +37 */ +38 public class PythonPackageAnalyzerTest extends BaseTest { +39 +40 /** +41 * The package analyzer to test. +42 */ +43 PythonPackageAnalyzer analyzer; +44 +45 /** +46 * Setup the PtyhonPackageAnalyzer. +47 * +48 * @throws Exception if there is a problem +49 */ +50 @Before +51 public void setUp() throws Exception { +52 analyzer = new PythonPackageAnalyzer(); +53 analyzer.setFilesMatched(true); +54 analyzer.initialize(); +55 } +56 +57 /** +58 * Cleanup any resources used. +59 * +60 * @throws Exception 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 of getName method, of class PythonPackageAnalyzer. +70 */ +71 @Test +72 public void testGetName() { +73 assertEquals("Analyzer name wrong.", "Python Package Analyzer", +74 analyzer.getName()); +75 } +76 +77 /** +78 * Test of supportsExtension method, of class PythonPackageAnalyzer. +79 */ +80 @Test +81 public void testSupportsFileExtension() { +82 assertTrue("Should support \"py\" extension.", +83 analyzer.accept(new File("test.py"))); +84 } +85 +86 @Test +87 public void testAnalyzeSourceMetadata() throws AnalysisException { +88 eggtestAssertions(this, +89 "python/eggtest/__init__.py"); 90 } 91 -92 /** -93 * Test of supportsExtension method, of class PythonPackageAnalyzer. -94 */ -95 @Test -96 public void testSupportsExtension() { -97 assertTrue("Should support \"py\" extension.", -98 analyzer.supportsExtension("py")); -99 } -100 -101 @Test -102 public void testAnalyzeSourceMetadata() throws AnalysisException { -103 eggtestAssertions(this, -104 "python/eggtest/__init__.py"); -105 } -106 -107 public void eggtestAssertions(Object context, final String resource) throws AnalysisException { -108 boolean found = false; -109 final Dependency result = new Dependency(BaseTest.getResourceAsFile( -110 context, resource)); -111 analyzer.analyze(result, null); -112 assertTrue("Expected vendor evidence to contain \"example\".", result -113 .getVendorEvidence().toString().contains("example")); -114 for (final Evidence e : result.getVersionEvidence()) { -115 if ("0.0.1".equals(e.getValue())) { -116 found = true; -117 break; -118 } -119 } -120 assertTrue("Version 0.0.1 not found in EggTest dependency.", found); -121 } -122 } +92 public void eggtestAssertions(Object context, final String resource) throws AnalysisException { +93 boolean found = false; +94 final Dependency result = new Dependency(BaseTest.getResourceAsFile( +95 context, resource)); +96 analyzer.analyze(result, null); +97 assertTrue("Expected vendor evidence to contain \"example\".", result +98 .getVendorEvidence().toString().contains("example")); +99 for (final Evidence e : result.getVersionEvidence()) { +100 if ("0.0.1".equals(e.getValue())) { +101 found = true; +102 break; +103 } +104 } +105 assertTrue("Version 0.0.1 not found in EggTest dependency.", found); +106 } +107 }
    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 f833e58f7..bada47fc7 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.2.11 Reference Package org.owasp.dependencycheck.analyzer + Dependency-Check Core 1.3.0 Reference Package org.owasp.dependencycheck.analyzer @@ -32,9 +32,18 @@
  • AssemblyAnalyzerTest +
  • +
  • + AutoconfAnalyzerTest +
  • +
  • + CMakeAnalyzerTest
  • CPEAnalyzerIntegrationTest +
  • +
  • + DependencyBundlingAnalyzerIntegrationTest
  • DependencyBundlingAnalyzerTest @@ -52,10 +61,10 @@ JarAnalyzerTest
  • - JavaScriptAnalyzerTest + NuspecAnalyzerTest
  • - NuspecAnalyzerTest + OpenSSLAnalyzerTest
  • PythonDistributionAnalyzerTest 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 988a9832a..a41d076a3 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.2.11 Reference Package org.owasp.dependencycheck.analyzer + Dependency-Check Core 1.3.0 Reference Package org.owasp.dependencycheck.analyzer @@ -64,11 +64,26 @@ AssemblyAnalyzerTest + + + + AutoconfAnalyzerTest + + + + + CMakeAnalyzerTest + CPEAnalyzerIntegrationTest + + + + DependencyBundlingAnalyzerIntegrationTest + @@ -97,12 +112,12 @@ - JavaScriptAnalyzerTest + NuspecAnalyzerTest - NuspecAnalyzerTest + OpenSSLAnalyzerTest diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/central/CentralSearchTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/central/CentralSearchTest.html index db9d5bb71..7bbae29df 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/central/CentralSearchTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/central/CentralSearchTest.html @@ -13,62 +13,63 @@ 5 import org.owasp.dependencycheck.BaseTest; 6 import org.owasp.dependencycheck.data.nexus.MavenArtifact; 7 import org.owasp.dependencycheck.utils.Settings; -8 -9 import java.io.FileNotFoundException; -10 import java.net.URL; -11 import java.util.List; -12 import java.util.logging.Logger; -13 -14 import static org.junit.Assert.*; -15 -16 /** -17 * Created by colezlaw on 10/13/14. -18 */ -19 public class CentralSearchTest extends BaseTest { -20 private static final Logger LOGGER = Logger.getLogger(CentralSearchTest.class.getName()); -21 private CentralSearch searcher; -22 -23 @Before -24 public void setUp() throws Exception { -25 String centralUrl = Settings.getString(Settings.KEYS.ANALYZER_CENTRAL_URL); -26 LOGGER.fine(centralUrl); -27 searcher = new CentralSearch(new URL(centralUrl)); -28 } -29 -30 @Test(expected = IllegalArgumentException.class) -31 public void testNullSha1() throws Exception { searcher.searchSha1(null); } -32 -33 @Test(expected = IllegalArgumentException.class) -34 public void testMalformedSha1() throws Exception { -35 searcher.searchSha1("invalid"); -36 } -37 -38 // This test does generate network traffic and communicates with a host -39 // you may not be able to reach. Remove the @Ignore annotation if you want to -40 // test it anyway -41 @Test -42 public void testValidSha1() throws Exception { -43 List<MavenArtifact> ma = searcher.searchSha1("9977a8d04e75609cf01badc4eb6a9c7198c4c5ea"); -44 assertEquals("Incorrect group", "org.apache.maven.plugins", ma.get(0).getGroupId()); -45 assertEquals("Incorrect artifact", "maven-compiler-plugin", ma.get(0).getArtifactId()); -46 assertEquals("Incorrect version", "3.1", ma.get(0).getVersion()); -47 } -48 -49 // This test does generate network traffic and communicates with a host -50 // you may not be able to reach. Remove the @Ignore annotation if you want to -51 // test it anyway -52 @Test(expected = FileNotFoundException.class) -53 public void testMissingSha1() throws Exception { -54 searcher.searchSha1("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); -55 } -56 -57 // This test should give us multiple results back from Central -58 @Test -59 public void testMultipleReturns() throws Exception { -60 List<MavenArtifact> ma = searcher.searchSha1("94A9CE681A42D0352B3AD22659F67835E560D107"); -61 assertTrue(ma.size() > 1); -62 } -63 } +8 import org.slf4j.Logger; +9 import org.slf4j.LoggerFactory; +10 +11 import java.io.FileNotFoundException; +12 import java.net.URL; +13 import java.util.List; +14 +15 import static org.junit.Assert.*; +16 +17 /** +18 * Created by colezlaw on 10/13/14. +19 */ +20 public class CentralSearchTest extends BaseTest { +21 private static final Logger LOGGER = LoggerFactory.getLogger(CentralSearchTest.class); +22 private CentralSearch searcher; +23 +24 @Before +25 public void setUp() throws Exception { +26 String centralUrl = Settings.getString(Settings.KEYS.ANALYZER_CENTRAL_URL); +27 LOGGER.debug(centralUrl); +28 searcher = new CentralSearch(new URL(centralUrl)); +29 } +30 +31 @Test(expected = IllegalArgumentException.class) +32 public void testNullSha1() throws Exception { searcher.searchSha1(null); } +33 +34 @Test(expected = IllegalArgumentException.class) +35 public void testMalformedSha1() throws Exception { +36 searcher.searchSha1("invalid"); +37 } +38 +39 // This test does generate network traffic and communicates with a host +40 // you may not be able to reach. Remove the @Ignore annotation if you want to +41 // test it anyway +42 @Test +43 public void testValidSha1() throws Exception { +44 List<MavenArtifact> ma = searcher.searchSha1("9977a8d04e75609cf01badc4eb6a9c7198c4c5ea"); +45 assertEquals("Incorrect group", "org.apache.maven.plugins", ma.get(0).getGroupId()); +46 assertEquals("Incorrect artifact", "maven-compiler-plugin", ma.get(0).getArtifactId()); +47 assertEquals("Incorrect version", "3.1", ma.get(0).getVersion()); +48 } +49 +50 // This test does generate network traffic and communicates with a host +51 // you may not be able to reach. Remove the @Ignore annotation if you want to +52 // test it anyway +53 @Test(expected = FileNotFoundException.class) +54 public void testMissingSha1() throws Exception { +55 searcher.searchSha1("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); +56 } +57 +58 // This test should give us multiple results back from Central +59 @Test +60 public void testMultipleReturns() throws Exception { +61 List<MavenArtifact> ma = searcher.searchSha1("94A9CE681A42D0352B3AD22659F67835E560D107"); +62 assertTrue(ma.size() > 1); +63 } +64 }
    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 861cc9035..681a9304b 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.2.11 Reference Package org.owasp.dependencycheck.data.central + Dependency-Check Core 1.3.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 73060ead2..c2befb328 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.2.11 Reference Package org.owasp.dependencycheck.data.central + Dependency-Check Core 1.3.0 Reference Package org.owasp.dependencycheck.data.central 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 2d9a46487..d5b70160f 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.2.11 Reference Package org.owasp.dependencycheck.data.cpe + Dependency-Check Core 1.3.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 42c7e8e2e..7379ffcc3 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.2.11 Reference Package org.owasp.dependencycheck.data.cpe + Dependency-Check Core 1.3.0 Reference Package org.owasp.dependencycheck.data.cpe 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 801808f29..0a61186fb 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.2.11 Reference Package org.owasp.dependencycheck.data.cwe + Dependency-Check Core 1.3.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 82b70b65f..d6730d807 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.2.11 Reference Package org.owasp.dependencycheck.data.cwe + Dependency-Check Core 1.3.0 Reference Package org.owasp.dependencycheck.data.cwe 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 1ce89ba8c..0fa23e4d2 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.2.11 Reference Package org.owasp.dependencycheck.data.lucene + Dependency-Check Core 1.3.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 8a7b9d948..cb36ef9be 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.2.11 Reference Package org.owasp.dependencycheck.data.lucene + Dependency-Check Core 1.3.0 Reference Package org.owasp.dependencycheck.data.lucene diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nexus/NexusSearchTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nexus/NexusSearchTest.html index 0f30d4800..d2ff4cf6a 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nexus/NexusSearchTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nexus/NexusSearchTest.html @@ -27,65 +27,66 @@ 19 20 import java.io.FileNotFoundException; 21 import java.net.URL; -22 import java.util.logging.Logger; -23 import static org.junit.Assert.assertEquals; -24 import static org.junit.Assert.assertNotNull; -25 import org.junit.Assume; -26 import org.junit.Before; -27 import org.junit.Ignore; -28 import org.junit.Test; -29 import org.owasp.dependencycheck.BaseTest; -30 import org.owasp.dependencycheck.utils.Settings; -31 -32 public class NexusSearchTest extends BaseTest { -33 -34 private static final Logger LOGGER = Logger.getLogger(NexusSearchTest.class.getName()); -35 private NexusSearch searcher; -36 -37 @Before -38 public void setUp() throws Exception { -39 String nexusUrl = Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL); -40 LOGGER.fine(nexusUrl); -41 searcher = new NexusSearch(new URL(nexusUrl)); -42 Assume.assumeTrue(searcher.preflightRequest()); -43 } -44 -45 @Test(expected = IllegalArgumentException.class) -46 @Ignore -47 public void testNullSha1() throws Exception { -48 searcher.searchSha1(null); -49 } -50 -51 @Test(expected = IllegalArgumentException.class) -52 @Ignore -53 public void testMalformedSha1() throws Exception { -54 searcher.searchSha1("invalid"); -55 } -56 -57 // This test does generate network traffic and communicates with a host -58 // you may not be able to reach. Remove the @Ignore annotation if you want to -59 // test it anyway -60 @Test -61 @Ignore -62 public void testValidSha1() throws Exception { -63 MavenArtifact ma = searcher.searchSha1("9977a8d04e75609cf01badc4eb6a9c7198c4c5ea"); -64 assertEquals("Incorrect group", "org.apache.maven.plugins", ma.getGroupId()); -65 assertEquals("Incorrect artifact", "maven-compiler-plugin", ma.getArtifactId()); -66 assertEquals("Incorrect version", "3.1", ma.getVersion()); -67 assertNotNull("URL Should not be null", ma.getArtifactUrl()); -68 } -69 -70 // This test does generate network traffic and communicates with a host -71 // you may not be able to reach. Remove the @Ignore annotation if you want to -72 // test it anyway -73 @Test(expected = FileNotFoundException.class) -74 @Ignore -75 public void testMissingSha1() throws Exception { -76 searcher.searchSha1("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); -77 } -78 } -79 -80 // vim: cc=120:sw=4:ts=4:sts=4 +22 import static org.junit.Assert.assertEquals; +23 import static org.junit.Assert.assertNotNull; +24 import org.junit.Assume; +25 import org.junit.Before; +26 import org.junit.Ignore; +27 import org.junit.Test; +28 import org.owasp.dependencycheck.BaseTest; +29 import org.owasp.dependencycheck.utils.Settings; +30 import org.slf4j.Logger; +31 import org.slf4j.LoggerFactory; +32 +33 public class NexusSearchTest extends BaseTest { +34 +35 private static final Logger LOGGER = LoggerFactory.getLogger(NexusSearchTest.class); +36 private NexusSearch searcher; +37 +38 @Before +39 public void setUp() throws Exception { +40 String nexusUrl = Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL); +41 LOGGER.debug(nexusUrl); +42 searcher = new NexusSearch(new URL(nexusUrl)); +43 Assume.assumeTrue(searcher.preflightRequest()); +44 } +45 +46 @Test(expected = IllegalArgumentException.class) +47 @Ignore +48 public void testNullSha1() throws Exception { +49 searcher.searchSha1(null); +50 } +51 +52 @Test(expected = IllegalArgumentException.class) +53 @Ignore +54 public void testMalformedSha1() throws Exception { +55 searcher.searchSha1("invalid"); +56 } +57 +58 // This test does generate network traffic and communicates with a host +59 // you may not be able to reach. Remove the @Ignore annotation if you want to +60 // test it anyway +61 @Test +62 @Ignore +63 public void testValidSha1() throws Exception { +64 MavenArtifact ma = searcher.searchSha1("9977a8d04e75609cf01badc4eb6a9c7198c4c5ea"); +65 assertEquals("Incorrect group", "org.apache.maven.plugins", ma.getGroupId()); +66 assertEquals("Incorrect artifact", "maven-compiler-plugin", ma.getArtifactId()); +67 assertEquals("Incorrect version", "3.1", ma.getVersion()); +68 assertNotNull("URL Should not be null", ma.getArtifactUrl()); +69 } +70 +71 // This test does generate network traffic and communicates with a host +72 // you may not be able to reach. Remove the @Ignore annotation if you want to +73 // test it anyway +74 @Test(expected = FileNotFoundException.class) +75 @Ignore +76 public void testMissingSha1() throws Exception { +77 searcher.searchSha1("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); +78 } +79 } +80 +81 // vim: cc=120:sw=4:ts=4:sts=4
    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 ed7d2af47..c43c301de 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.2.11 Reference Package org.owasp.dependencycheck.data.nexus + Dependency-Check Core 1.3.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 29bb21eb9..4e00d7c80 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.2.11 Reference Package org.owasp.dependencycheck.data.nexus + Dependency-Check Core 1.3.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 41db532da..af1158741 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.2.11 Reference Package org.owasp.dependencycheck.data.nuget + Dependency-Check Core 1.3.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 ac4c4f16c..8bb24b61d 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.2.11 Reference Package org.owasp.dependencycheck.data.nuget + Dependency-Check Core 1.3.0 Reference Package org.owasp.dependencycheck.data.nuget diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/BaseDBTestCase.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/BaseDBTestCase.html index 3db37242c..f890be1ef 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/BaseDBTestCase.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/BaseDBTestCase.html @@ -30,13 +30,13 @@ 22 import java.io.File; 23 import java.io.FileInputStream; 24 import java.io.FileOutputStream; -25 import java.util.logging.Level; -26 import java.util.logging.Logger; -27 import java.util.zip.ZipEntry; -28 import java.util.zip.ZipInputStream; -29 import org.junit.Before; -30 import org.owasp.dependencycheck.BaseTest; -31 import org.owasp.dependencycheck.utils.Settings; +25 import java.util.zip.ZipEntry; +26 import java.util.zip.ZipInputStream; +27 import org.junit.Before; +28 import org.owasp.dependencycheck.BaseTest; +29 import org.owasp.dependencycheck.utils.Settings; +30 import org.slf4j.Logger; +31 import org.slf4j.LoggerFactory; 32 33 /** 34 * @@ -46,82 +46,87 @@ 38 39 protected final static int BUFFER_SIZE = 2048; 40 -41 @Before -42 public void setUp() throws Exception { -43 ensureDBExists(); -44 } -45 -46 public static void ensureDBExists() throws Exception { +41 private final static Logger LOGGER = LoggerFactory.getLogger(BaseDBTestCase.class); +42 +43 @Before +44 public void setUp() throws Exception { +45 ensureDBExists(); +46 } 47 -48 java.io.File dataPath = Settings.getDataDirectory(); -49 String fileName = String.format(Settings.getString(Settings.KEYS.DB_FILE_NAME), Settings.getString(Settings.KEYS.DB_VERSION)); -50 java.io.File dataFile = new File(dataPath, fileName); -51 if (!dataPath.exists() || !dataFile.exists()) { -52 dataPath.mkdirs(); -53 FileInputStream fis = null; -54 ZipInputStream zin = null; -55 try { -56 File path = new File(BaseDBTestCase.class.getClassLoader().getResource("data.zip").getPath()); -57 fis = new FileInputStream(path); -58 zin = new ZipInputStream(new BufferedInputStream(fis)); -59 ZipEntry entry; -60 while ((entry = zin.getNextEntry()) != null) { -61 if (entry.isDirectory()) { -62 final File d = new File(dataPath, entry.getName()); -63 d.mkdir(); -64 continue; -65 } -66 FileOutputStream fos = null; -67 BufferedOutputStream dest = null; -68 try { -69 File o = new File(dataPath, entry.getName()); -70 o.createNewFile(); -71 fos = new FileOutputStream(o, false); -72 dest = new BufferedOutputStream(fos, BUFFER_SIZE); -73 byte data[] = new byte[BUFFER_SIZE]; -74 int count; -75 while ((count = zin.read(data, 0, BUFFER_SIZE)) != -1) { -76 dest.write(data, 0, count); -77 } -78 } catch (Throwable ex) { -79 Logger.getLogger(BaseDBTestCase.class.getName()).log(Level.SEVERE, null, ex); -80 } finally { -81 try { -82 if (dest != null) { -83 dest.flush(); -84 dest.close(); -85 } -86 } catch (Throwable ex) { -87 Logger.getLogger(BaseDBTestCase.class.getName()).log(Level.FINEST, null, ex); -88 } -89 try { -90 if (fos != null) { -91 fos.close(); -92 } -93 } catch (Throwable ex) { -94 Logger.getLogger(BaseDBTestCase.class.getName()).log(Level.FINEST, null, ex); -95 } -96 } -97 } -98 } finally { -99 try { -100 if (zin != null) { -101 zin.close(); -102 } -103 } catch (Throwable ex) { -104 Logger.getLogger(BaseDBTestCase.class.getName()).log(Level.FINEST, null, ex); -105 } -106 try { -107 if (fis != null) { -108 fis.close(); -109 } -110 } catch (Throwable ex) { -111 Logger.getLogger(BaseDBTestCase.class.getName()).log(Level.FINEST, null, ex); -112 } -113 } -114 } -115 } -116 } +48 public static void ensureDBExists() throws Exception { +49 +50 java.io.File dataPath = Settings.getDataDirectory(); +51 String fileName = Settings.getString(Settings.KEYS.DB_FILE_NAME); +52 LOGGER.trace("DB file name {}", fileName); +53 java.io.File dataFile = new File(dataPath, fileName); +54 LOGGER.trace("Ensuring {} exists", dataFile.toString()); +55 if (!dataPath.exists() || !dataFile.exists()) { +56 LOGGER.trace("Extracting database to {}", dataPath.toString()); +57 dataPath.mkdirs(); +58 FileInputStream fis = null; +59 ZipInputStream zin = null; +60 try { +61 File path = new File(BaseDBTestCase.class.getClassLoader().getResource("data.zip").getPath()); +62 fis = new FileInputStream(path); +63 zin = new ZipInputStream(new BufferedInputStream(fis)); +64 ZipEntry entry; +65 while ((entry = zin.getNextEntry()) != null) { +66 if (entry.isDirectory()) { +67 final File d = new File(dataPath, entry.getName()); +68 d.mkdir(); +69 continue; +70 } +71 FileOutputStream fos = null; +72 BufferedOutputStream dest = null; +73 try { +74 File o = new File(dataPath, entry.getName()); +75 o.createNewFile(); +76 fos = new FileOutputStream(o, false); +77 dest = new BufferedOutputStream(fos, BUFFER_SIZE); +78 byte data[] = new byte[BUFFER_SIZE]; +79 int count; +80 while ((count = zin.read(data, 0, BUFFER_SIZE)) != -1) { +81 dest.write(data, 0, count); +82 } +83 } catch (Throwable ex) { +84 LOGGER.error("", ex); +85 } finally { +86 try { +87 if (dest != null) { +88 dest.flush(); +89 dest.close(); +90 } +91 } catch (Throwable ex) { +92 LOGGER.trace("", ex); +93 } +94 try { +95 if (fos != null) { +96 fos.close(); +97 } +98 } catch (Throwable ex) { +99 LOGGER.trace("", ex); +100 } +101 } +102 } +103 } finally { +104 try { +105 if (zin != null) { +106 zin.close(); +107 } +108 } catch (Throwable ex) { +109 LOGGER.trace("", ex); +110 } +111 try { +112 if (fis != null) { +113 fis.close(); +114 } +115 } catch (Throwable ex) { +116 LOGGER.trace("", ex); +117 } +118 } +119 } +120 } +121 }
    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 e282d3790..ddafb15eb 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 @@ -47,57 +47,57 @@ 39 */ 40 @Test 41 public void testOpen() throws Exception { -42 CveDB instance = new CveDB(); -43 instance.open(); -44 instance.commit(); -45 instance.close(); -46 } -47 -48 /** -49 * Test of getCPEs method, of class CveDB. -50 */ -51 @Test -52 public void testGetCPEs() throws Exception { -53 CveDB instance = new CveDB(); -54 try { -55 String vendor = "apache"; -56 String product = "struts"; -57 instance.open(); -58 Set<VulnerableSoftware> result = instance.getCPEs(vendor, product); -59 assertTrue(result.size() > 5); -60 } finally { -61 instance.close(); -62 } -63 } -64 -65 /** -66 * Test of getVulnerabilities method, of class CveDB. -67 */ -68 @Test -69 public void testGetVulnerabilities() throws Exception { -70 String cpeStr = "cpe:/a:apache:struts:2.1.2"; -71 CveDB instance = new CveDB(); -72 List<Vulnerability> results; -73 try { -74 instance.open(); -75 results = instance.getVulnerabilities(cpeStr); -76 assertTrue(results.size() > 5); -77 cpeStr = "cpe:/a:jruby:jruby:1.6.3"; -78 results = instance.getVulnerabilities(cpeStr); -79 assertTrue(results.size() > 1); -80 -81 boolean found = false; -82 String expected = "CVE-2011-4838"; -83 for (Vulnerability v : results) { -84 if (expected.equals(v.getName())) { -85 found = true; -86 break; -87 } -88 } -89 assertTrue("Expected " + expected + ", but was not identified", found); +42 CveDB instance = null; +43 try { +44 instance = new CveDB(); +45 instance.open(); +46 instance.commit(); +47 } finally { +48 if (instance != null) { +49 instance.close(); +50 } +51 } +52 } +53 +54 /** +55 * Test of getCPEs method, of class CveDB. +56 */ +57 @Test +58 public void testGetCPEs() throws Exception { +59 CveDB instance = null; +60 try { +61 instance = new CveDB(); +62 String vendor = "apache"; +63 String product = "struts"; +64 instance.open(); +65 Set<VulnerableSoftware> result = instance.getCPEs(vendor, product); +66 assertTrue(result.size() > 5); +67 } finally { +68 if (instance != null) { +69 instance.close(); +70 } +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 = null; +81 List<Vulnerability> results; +82 try { +83 instance = new CveDB(); +84 instance.open(); +85 results = instance.getVulnerabilities(cpeStr); +86 assertTrue(results.size() > 5); +87 cpeStr = "cpe:/a:jruby:jruby:1.6.3"; +88 results = instance.getVulnerabilities(cpeStr); +89 assertTrue(results.size() > 1); 90 -91 found = false; -92 expected = "CVE-2012-5370"; +91 boolean found = false; +92 String expected = "CVE-2011-4838"; 93 for (Vulnerability v : results) { 94 if (expected.equals(v.getName())) { 95 found = true; @@ -106,69 +106,86 @@ 98 } 99 assertTrue("Expected " + expected + ", but was not identified", found); 100 -101 } finally { -102 instance.close(); -103 } -104 } -105 -106 /** -107 * Test of getMatchingSoftware method, of class CveDB. -108 */ -109 @Test -110 public void testGetMatchingSoftware() throws Exception { -111 HashMap<String, Boolean> versions = new HashMap<String, Boolean>(); -112 DependencyVersion identifiedVersion = new DependencyVersion("1.0.1o"); -113 versions.put("cpe:/a:openssl:openssl:1.0.1e", Boolean.FALSE); -114 -115 CveDB instance = new CveDB(); -116 Entry<String, Boolean> results = instance.getMatchingSoftware(versions, "openssl", "openssl", identifiedVersion); -117 Assert.assertNull(results); -118 versions.put("cpe:/a:openssl:openssl:1.0.1p", Boolean.FALSE); -119 results = instance.getMatchingSoftware(versions, "openssl", "openssl", identifiedVersion); -120 Assert.assertNull(results); -121 -122 versions.put("cpe:/a:openssl:openssl:1.0.1q", Boolean.TRUE); -123 results = instance.getMatchingSoftware(versions, "openssl", "openssl", identifiedVersion); -124 Assert.assertNotNull(results); -125 Assert.assertEquals("cpe:/a:openssl:openssl:1.0.1q", results.getKey()); -126 -127 versions.clear(); -128 -129 versions.put("cpe:/a:springsource:spring_framework:3.2.5", Boolean.FALSE); -130 versions.put("cpe:/a:springsource:spring_framework:3.2.6", Boolean.FALSE); -131 versions.put("cpe:/a:springsource:spring_framework:3.2.7", Boolean.TRUE); -132 -133 versions.put("cpe:/a:springsource:spring_framework:4.0.1", Boolean.TRUE); -134 versions.put("cpe:/a:springsource:spring_framework:4.0.0:m1", Boolean.FALSE); -135 versions.put("cpe:/a:springsource:spring_framework:4.0.0:m2", Boolean.FALSE); -136 versions.put("cpe:/a:springsource:spring_framework:4.0.0:rc1", Boolean.FALSE); -137 -138 identifiedVersion = new DependencyVersion("3.2.2"); -139 results = instance.getMatchingSoftware(versions, "springsource", "spring_framework", identifiedVersion); -140 Assert.assertEquals("cpe:/a:springsource:spring_framework:3.2.7", results.getKey()); -141 Assert.assertTrue(results.getValue()); -142 identifiedVersion = new DependencyVersion("3.2.12"); -143 results = instance.getMatchingSoftware(versions, "springsource", "spring_framework", identifiedVersion); -144 Assert.assertNull(results); +101 found = false; +102 expected = "CVE-2012-5370"; +103 for (Vulnerability v : results) { +104 if (expected.equals(v.getName())) { +105 found = true; +106 break; +107 } +108 } +109 assertTrue("Expected " + expected + ", but was not identified", found); +110 +111 } finally { +112 if (instance != null) { +113 instance.close(); +114 } +115 } +116 } +117 +118 /** +119 * Test of getMatchingSoftware method, of class CveDB. +120 */ +121 @Test +122 public void testGetMatchingSoftware() throws Exception { +123 CveDB instance = null; +124 HashMap<String, Boolean> versions = new HashMap<String, Boolean>(); +125 DependencyVersion identifiedVersion = new DependencyVersion("1.0.1o"); +126 versions.put("cpe:/a:openssl:openssl:1.0.1e", Boolean.FALSE); +127 try { +128 instance = new CveDB(); +129 Entry<String, Boolean> results = instance.getMatchingSoftware(versions, "openssl", "openssl", identifiedVersion); +130 Assert.assertNull(results); +131 versions.put("cpe:/a:openssl:openssl:1.0.1p", Boolean.FALSE); +132 results = instance.getMatchingSoftware(versions, "openssl", "openssl", identifiedVersion); +133 Assert.assertNull(results); +134 +135 versions.put("cpe:/a:openssl:openssl:1.0.1q", Boolean.TRUE); +136 results = instance.getMatchingSoftware(versions, "openssl", "openssl", identifiedVersion); +137 Assert.assertNotNull(results); +138 Assert.assertEquals("cpe:/a:openssl:openssl:1.0.1q", results.getKey()); +139 +140 versions.clear(); +141 +142 versions.put("cpe:/a:springsource:spring_framework:3.2.5", Boolean.FALSE); +143 versions.put("cpe:/a:springsource:spring_framework:3.2.6", Boolean.FALSE); +144 versions.put("cpe:/a:springsource:spring_framework:3.2.7", Boolean.TRUE); 145 -146 identifiedVersion = new DependencyVersion("4.0.0"); -147 results = instance.getMatchingSoftware(versions, "springsource", "spring_framework", identifiedVersion); -148 Assert.assertEquals("cpe:/a:springsource:spring_framework:4.0.1", results.getKey()); -149 Assert.assertTrue(results.getValue()); -150 identifiedVersion = new DependencyVersion("4.1.0"); -151 results = instance.getMatchingSoftware(versions, "springsource", "spring_framework", identifiedVersion); -152 Assert.assertNull(results); -153 -154 versions.clear(); -155 -156 versions.put("cpe:/a:jruby:jruby:-", Boolean.FALSE); -157 identifiedVersion = new DependencyVersion("1.6.3"); -158 results = instance.getMatchingSoftware(versions, "springsource", "spring_framework", identifiedVersion); -159 Assert.assertNotNull(results); -160 -161 } -162 -163 } +146 versions.put("cpe:/a:springsource:spring_framework:4.0.1", Boolean.TRUE); +147 versions.put("cpe:/a:springsource:spring_framework:4.0.0:m1", Boolean.FALSE); +148 versions.put("cpe:/a:springsource:spring_framework:4.0.0:m2", Boolean.FALSE); +149 versions.put("cpe:/a:springsource:spring_framework:4.0.0:rc1", Boolean.FALSE); +150 +151 identifiedVersion = new DependencyVersion("3.2.2"); +152 results = instance.getMatchingSoftware(versions, "springsource", "spring_framework", identifiedVersion); +153 Assert.assertEquals("cpe:/a:springsource:spring_framework:3.2.7", results.getKey()); +154 Assert.assertTrue(results.getValue()); +155 identifiedVersion = new DependencyVersion("3.2.12"); +156 results = instance.getMatchingSoftware(versions, "springsource", "spring_framework", identifiedVersion); +157 Assert.assertNull(results); +158 +159 identifiedVersion = new DependencyVersion("4.0.0"); +160 results = instance.getMatchingSoftware(versions, "springsource", "spring_framework", identifiedVersion); +161 Assert.assertEquals("cpe:/a:springsource:spring_framework:4.0.1", results.getKey()); +162 Assert.assertTrue(results.getValue()); +163 identifiedVersion = new DependencyVersion("4.1.0"); +164 results = instance.getMatchingSoftware(versions, "springsource", "spring_framework", identifiedVersion); +165 Assert.assertNull(results); +166 +167 versions.clear(); +168 +169 versions.put("cpe:/a:jruby:jruby:-", Boolean.FALSE); +170 identifiedVersion = new DependencyVersion("1.6.3"); +171 results = instance.getMatchingSoftware(versions, "springsource", "spring_framework", identifiedVersion); +172 Assert.assertNotNull(results); +173 } finally { +174 if (instance != null) { +175 instance.close(); +176 } +177 } +178 } +179 +180 }
    diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/DatabasePropertiesIntegrationTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/DatabasePropertiesIntegrationTest.html index 0b6ec86da..2588517aa 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/DatabasePropertiesIntegrationTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/nvdcve/DatabasePropertiesIntegrationTest.html @@ -29,7 +29,7 @@ 21 import static org.junit.Assert.assertEquals; 22 import static org.junit.Assert.assertTrue; 23 import org.junit.Test; -24 import org.owasp.dependencycheck.data.update.NvdCveInfo; +24 import org.owasp.dependencycheck.data.update.nvd.NvdCveInfo; 25 26 /** 27 * @@ -42,85 +42,115 @@ 34 */ 35 @Test 36 public void testIsEmpty() throws Exception { -37 CveDB cveDB = new CveDB(); -38 cveDB.open(); -39 DatabaseProperties instance = cveDB.getDatabaseProperties(); -40 boolean expResult = false; -41 boolean result = instance.isEmpty(); -42 //no exception means the call worked... whether or not it is empty depends on if the db is new -43 //assertEquals(expResult, result); -44 cveDB.close(); -45 } -46 -47 /** -48 * Test of save method, of class DatabaseProperties. -49 */ -50 @Test -51 public void testSave() throws Exception { -52 NvdCveInfo updatedValue = new NvdCveInfo(); -53 String key = "test"; -54 long expected = 1337; -55 updatedValue.setId(key); -56 updatedValue.setTimestamp(expected); -57 CveDB cveDB = new CveDB(); -58 cveDB.open(); -59 DatabaseProperties instance = cveDB.getDatabaseProperties(); -60 instance.save(updatedValue); -61 //reload the properties -62 cveDB.close(); -63 cveDB = new CveDB(); -64 cveDB.open(); -65 instance = cveDB.getDatabaseProperties(); -66 cveDB.close(); -67 long results = Long.parseLong(instance.getProperty("NVD CVE " + key)); -68 assertEquals(expected, results); -69 } -70 -71 /** -72 * Test of getProperty method, of class DatabaseProperties. -73 */ -74 @Test -75 public void testGetProperty_String_String() throws Exception { -76 String key = "doesn't exist"; -77 String defaultValue = "default"; -78 CveDB cveDB = new CveDB(); -79 cveDB.open(); -80 DatabaseProperties instance = cveDB.getDatabaseProperties(); -81 cveDB.close(); -82 String expResult = "default"; -83 String result = instance.getProperty(key, defaultValue); -84 assertEquals(expResult, result); -85 } -86 -87 /** -88 * Test of getProperty method, of class DatabaseProperties. -89 */ -90 @Test -91 public void testGetProperty_String() throws DatabaseException { -92 String key = "version"; -93 CveDB cveDB = new CveDB(); -94 cveDB.open(); -95 DatabaseProperties instance = cveDB.getDatabaseProperties(); -96 cveDB.close(); -97 String result = instance.getProperty(key); -98 double version = Double.parseDouble(result); -99 assertTrue(version >= 2.8); -100 assertTrue(version <= 10); -101 } -102 -103 /** -104 * Test of getProperties method, of class DatabaseProperties. -105 */ -106 @Test -107 public void testGetProperties() throws DatabaseException { -108 CveDB cveDB = new CveDB(); -109 cveDB.open(); -110 DatabaseProperties instance = cveDB.getDatabaseProperties(); -111 cveDB.close(); -112 Properties result = instance.getProperties(); -113 assertTrue(result.size() > 0); -114 } -115 } +37 CveDB cveDB = null; +38 try { +39 cveDB = new CveDB(); +40 cveDB.open(); +41 DatabaseProperties instance = cveDB.getDatabaseProperties(); +42 boolean expResult = false; +43 boolean result = instance.isEmpty(); +44 //no exception means the call worked... whether or not it is empty depends on if the db is new +45 //assertEquals(expResult, result); +46 } finally { +47 if (cveDB != null) { +48 cveDB.close(); +49 } +50 } +51 } +52 +53 /** +54 * Test of save method, of class DatabaseProperties. +55 */ +56 @Test +57 public void testSave() throws Exception { +58 NvdCveInfo updatedValue = new NvdCveInfo(); +59 String key = "test"; +60 long expected = 1337; +61 updatedValue.setId(key); +62 updatedValue.setTimestamp(expected); +63 CveDB cveDB = null; +64 try { +65 cveDB = new CveDB(); +66 cveDB.open(); +67 DatabaseProperties instance = cveDB.getDatabaseProperties(); +68 instance.save(updatedValue); +69 //reload the properties +70 cveDB.close(); +71 cveDB = new CveDB(); +72 cveDB.open(); +73 instance = cveDB.getDatabaseProperties(); +74 long results = Long.parseLong(instance.getProperty("NVD CVE " + key)); +75 assertEquals(expected, results); +76 } finally { +77 if (cveDB != null) { +78 cveDB.close(); +79 } +80 } +81 } +82 +83 /** +84 * Test of getProperty method, of class DatabaseProperties. +85 */ +86 @Test +87 public void testGetProperty_String_String() throws Exception { +88 String key = "doesn't exist"; +89 String defaultValue = "default"; +90 CveDB cveDB = null; +91 try { +92 cveDB = new CveDB(); +93 cveDB.open(); +94 DatabaseProperties instance = cveDB.getDatabaseProperties(); +95 String expResult = "default"; +96 String result = instance.getProperty(key, defaultValue); +97 assertEquals(expResult, result); +98 } finally { +99 if (cveDB != null) { +100 cveDB.close(); +101 } +102 } +103 } +104 +105 /** +106 * Test of getProperty method, of class DatabaseProperties. +107 */ +108 @Test +109 public void testGetProperty_String() throws DatabaseException { +110 String key = "version"; +111 CveDB cveDB = null; +112 try { +113 cveDB = new CveDB(); +114 cveDB.open(); +115 DatabaseProperties instance = cveDB.getDatabaseProperties(); +116 String result = instance.getProperty(key); +117 double version = Double.parseDouble(result); +118 assertTrue(version >= 2.8); +119 assertTrue(version <= 10); +120 } finally { +121 if (cveDB != null) { +122 cveDB.close(); +123 } +124 } +125 } +126 +127 /** +128 * Test of getProperties method, of class DatabaseProperties. +129 */ +130 @Test +131 public void testGetProperties() throws DatabaseException { +132 CveDB cveDB = null; +133 try { +134 cveDB = new CveDB(); +135 cveDB.open(); +136 DatabaseProperties instance = cveDB.getDatabaseProperties(); +137 Properties result = instance.getProperties(); +138 assertTrue(result.size() > 0); +139 } finally { +140 if (cveDB != null) { +141 cveDB.close(); +142 } +143 } +144 } +145 }
    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 ddc3747f4..019c2d20f 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.2.11 Reference Package org.owasp.dependencycheck.data.nvdcve + Dependency-Check Core 1.3.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 3d9c43183..2bcd4116a 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.2.11 Reference Package org.owasp.dependencycheck.data.nvdcve + Dependency-Check Core 1.3.0 Reference Package org.owasp.dependencycheck.data.nvdcve diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/BaseUpdaterTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/BaseUpdaterTest.html new file mode 100644 index 000000000..dc4183a46 --- /dev/null +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/BaseUpdaterTest.html @@ -0,0 +1,113 @@ + + + +BaseUpdaterTest 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) 2015 Jeremy Long. All Rights Reserved.
    +17   */
    +18  package org.owasp.dependencycheck.data.update;
    +19  
    +20  import org.junit.Test;
    +21  import org.owasp.dependencycheck.data.nvdcve.BaseDBTestCase;
    +22  import org.owasp.dependencycheck.data.nvdcve.CveDB;
    +23  import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties;
    +24  import org.owasp.dependencycheck.data.update.exception.UpdateException;
    +25  
    +26  import static org.junit.Assert.assertEquals;
    +27  import static org.junit.Assert.assertTrue;
    +28  
    +29  /**
    +30   *
    +31   * @author Jeremy Long
    +32   */
    +33  public class BaseUpdaterTest extends BaseDBTestCase {
    +34  
    +35      /**
    +36       * Test of getCveDB method, of class BaseUpdater.
    +37       */
    +38      @Test
    +39      public void testGetCveDB() {
    +40          BaseUpdater instance = new BaseUpdaterImpl();
    +41          CveDB expResult = null;
    +42          CveDB result = instance.getCveDB();
    +43          assertEquals(expResult, result);
    +44      }
    +45  
    +46      /**
    +47       * Test of getProperties method, of class BaseUpdater.
    +48       */
    +49      @Test
    +50      public void testGetProperties() throws UpdateException {
    +51          BaseUpdater instance = null;
    +52          try {
    +53              instance = new BaseUpdaterImpl();
    +54              instance.openDataStores();
    +55  
    +56              DatabaseProperties result = instance.getProperties();
    +57              assertTrue(result.getProperties().keySet().size() > 1);
    +58          } finally {
    +59              if (instance != null) {
    +60                  instance.closeDataStores();
    +61              }
    +62          }
    +63      }
    +64  
    +65      /**
    +66       * Test of closeDataStores method, of class BaseUpdater.
    +67       */
    +68      @Test
    +69      public void testCloseDataStores() throws UpdateException {
    +70          BaseUpdater instance = null;
    +71          try {
    +72              instance = new BaseUpdaterImpl();
    +73              instance.openDataStores();
    +74          } finally {
    +75              if (instance != null) {
    +76                  instance.closeDataStores();
    +77              }
    +78          }
    +79      }
    +80  
    +81      /**
    +82       * Test of openDataStores method, of class BaseUpdater.
    +83       */
    +84      @Test
    +85      public void testOpenDataStores() throws Exception {
    +86          BaseUpdater instance = null;
    +87          try {
    +88              instance = new BaseUpdaterImpl();
    +89              instance.openDataStores();
    +90          } finally {
    +91              if (instance != null) {
    +92                  instance.closeDataStores();
    +93              }
    +94          }
    +95      }
    +96  
    +97      public class BaseUpdaterImpl extends BaseUpdater {
    +98      }
    +99  
    +100 }
    +
    +
    + + + diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/CpeUpdaterIntegrationTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/CpeUpdaterIntegrationTest.html new file mode 100644 index 000000000..0d09b25d3 --- /dev/null +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/CpeUpdaterIntegrationTest.html @@ -0,0 +1,56 @@ + + + +CpeUpdaterIntegrationTest xref + + + +
    +1   /*
    +2    * Copyright 2015 OWASP.
    +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  package org.owasp.dependencycheck.data.update;
    +17  
    +18  import org.junit.After;
    +19  import org.junit.AfterClass;
    +20  import org.junit.Before;
    +21  import org.junit.BeforeClass;
    +22  import org.junit.Test;
    +23  import static org.junit.Assert.*;
    +24  import org.owasp.dependencycheck.BaseTest;
    +25  
    +26  /**
    +27   *
    +28   * @author jeremy
    +29   */
    +30  public class CpeUpdaterIntegrationTest extends BaseTest {
    +31  
    +32      /**
    +33       * Test of update method, of class CpeUpdater.
    +34       */
    +35      @Test
    +36      public void testUpdate() throws Exception {
    +37          //commented out as the current code base does not utilize the CpeU[pdater.
    +38  
    +39  //        CpeUpdater instance = new CpeUpdater();
    +40  //        instance.update();
    +41      }
    +42  
    +43  }
    +
    +
    + + + diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/NvdCveUpdaterIntegrationTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/NvdCveUpdaterIntegrationTest.html index 128242fa5..ee880d0df 100644 --- a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/NvdCveUpdaterIntegrationTest.html +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/NvdCveUpdaterIntegrationTest.html @@ -25,55 +25,50 @@ 17 */ 18 package org.owasp.dependencycheck.data.update; 19 -20 import java.io.File; -21 import java.util.Calendar; -22 import org.junit.Before; -23 import org.junit.Test; -24 import org.owasp.dependencycheck.BaseTest; -25 import org.owasp.dependencycheck.utils.Settings; -26 -27 /** -28 * -29 * @author Jeremy Long -30 */ -31 public class NvdCveUpdaterIntegrationTest extends BaseTest { -32 -33 @Before -34 public void setUp() throws Exception { -35 int year = Calendar.getInstance().get(Calendar.YEAR); -36 if (year <= 2014) { -37 //File f = new File(NvdCveUpdaterIntegrationTest.class.getClassLoader().getResource("nvdcve-2.0-2014.xml").getPath()); -38 File f = BaseTest.getResourceAsFile(this, "nvdcve-2.0-2014.xml"); -39 String baseURL = f.toURI().toURL().toString(); -40 String modified12 = baseURL.replace("nvdcve-2.0-2014.xml", "nvdcve-modified.xml"); -41 String modified20 = baseURL.replace("nvdcve-2.0-2014.xml", "nvdcve-2.0-modified.xml"); -42 String full12 = baseURL.replace("nvdcve-2.0-2014.xml", "nvdcve-%d.xml"); -43 String full20 = baseURL.replace("nvdcve-2.0-2014.xml", "nvdcve-2.0-%d.xml"); -44 // cve.url-1.2.modified=http://nvd.nist.gov/download/nvdcve-modified.xml -45 // cve.url-2.0.modified=http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-modified.xml -46 // cve.startyear=2014 -47 // cve.url-2.0.base=http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-%d.xml -48 // cve.url-1.2.base=http://nvd.nist.gov/download/nvdcve-%d.xml -49 -50 Settings.setString(Settings.KEYS.CVE_MODIFIED_12_URL, modified12); -51 Settings.setString(Settings.KEYS.CVE_MODIFIED_20_URL, modified20); -52 Settings.setString(Settings.KEYS.CVE_SCHEMA_1_2, full12); -53 Settings.setString(Settings.KEYS.CVE_SCHEMA_2_0, full20); -54 Settings.setString(Settings.KEYS.CVE_START_YEAR, "2014"); -55 } else { -56 System.err.println("Consider updating the local data files to make the NvdCveUpdaterIntegrationTest perform faster"); -57 } -58 } -59 -60 /** -61 * Test of update method, of class NvdCveUpdater. -62 */ -63 @Test -64 public void testUpdate() throws Exception { -65 NvdCveUpdater instance = new NvdCveUpdater(); -66 instance.update(); -67 } -68 } +20 import java.net.MalformedURLException; +21 import static org.junit.Assert.assertNotNull; +22 import org.junit.Test; +23 import org.owasp.dependencycheck.BaseTest; +24 import org.owasp.dependencycheck.data.update.exception.UpdateException; +25 import org.owasp.dependencycheck.data.update.nvd.UpdateableNvdCve; +26 import org.owasp.dependencycheck.utils.DownloadFailedException; +27 +28 /** +29 * +30 * @author Jeremy Long +31 */ +32 public class NvdCveUpdaterIntegrationTest extends BaseTest { +33 +34 public NvdCveUpdater getUpdater() throws MalformedURLException, DownloadFailedException, UpdateException { +35 NvdCveUpdater instance = new NvdCveUpdater(); +36 return instance; +37 } +38 +39 // test removed as it is duplicative of the EngineIntegrationTest and the NvdCveUpdaterIntergraionTest +40 // /** +41 // * Test of update method, of class StandardUpdate. +42 // */ +43 // @Test +44 // public void testUpdate() throws Exception { +45 // StandardUpdate instance = getStandardUpdateTask(); +46 // instance.update(); +47 // //TODO make this an actual test +48 // } +49 /** +50 * Test of updatesNeeded method, of class StandardUpdate. +51 */ +52 @Test +53 public void testUpdatesNeeded() throws Exception { +54 NvdCveUpdater instance = getUpdater(); +55 try { +56 instance.openDataStores(); +57 UpdateableNvdCve result = instance.getUpdatesNeeded(); +58 assertNotNull(result); +59 } finally { +60 instance.closeDataStores(); +61 } +62 } +63 }
    diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/DownloadTaskTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/DownloadTaskTest.html new file mode 100644 index 000000000..13a4dc338 --- /dev/null +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/DownloadTaskTest.html @@ -0,0 +1,90 @@ + + + +DownloadTaskTest 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) 2014 Jeremy Long. All Rights Reserved.
    +17   */
    +18  package org.owasp.dependencycheck.data.update.nvd;
    +19  
    +20  import org.owasp.dependencycheck.data.update.nvd.ProcessTask;
    +21  import org.owasp.dependencycheck.data.update.nvd.DownloadTask;
    +22  import java.util.concurrent.ExecutorService;
    +23  import java.util.concurrent.Future;
    +24  import org.junit.After;
    +25  import org.junit.AfterClass;
    +26  import static org.junit.Assert.assertNull;
    +27  import org.junit.Before;
    +28  import org.junit.BeforeClass;
    +29  import org.junit.Test;
    +30  import org.owasp.dependencycheck.data.nvdcve.CveDB;
    +31  import org.owasp.dependencycheck.data.update.nvd.NvdCveInfo;
    +32  import org.owasp.dependencycheck.utils.Settings;
    +33  
    +34  /**
    +35   *
    +36   * @author Jeremy Long
    +37   */
    +38  public class DownloadTaskTest {
    +39  
    +40      public DownloadTaskTest() {
    +41      }
    +42  
    +43      @BeforeClass
    +44      public static void setUpClass() {
    +45      }
    +46  
    +47      @AfterClass
    +48      public static void tearDownClass() {
    +49      }
    +50  
    +51      @Before
    +52      public void setUp() {
    +53          Settings.initialize();
    +54      }
    +55  
    +56      @After
    +57      public void tearDown() {
    +58          Settings.cleanup();
    +59      }
    +60  
    +61      /**
    +62       * Test of call method, of class DownloadTask.
    +63       */
    +64      @Test
    +65      public void testCall() throws Exception {
    +66          NvdCveInfo cve = new NvdCveInfo();
    +67          cve.setId("modified");
    +68          cve.setNeedsUpdate(true);
    +69          cve.setUrl(Settings.getString(Settings.KEYS.CVE_MODIFIED_20_URL));
    +70          cve.setOldSchemaVersionUrl(Settings.getString(Settings.KEYS.CVE_MODIFIED_12_URL));
    +71          ExecutorService processExecutor = null;
    +72          CveDB cveDB = null;
    +73          DownloadTask instance = new DownloadTask(cve, processExecutor, cveDB, Settings.getInstance());
    +74          Future<ProcessTask> result = instance.call();
    +75          assertNull(result);
    +76      }
    +77  }
    +
    +
    + + + diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCveInfoTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCveInfoTest.html new file mode 100644 index 000000000..a91a85792 --- /dev/null +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCveInfoTest.html @@ -0,0 +1,104 @@ + + + +NvdCveInfoTest 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.data.update.nvd;
    +19  
    +20  import org.owasp.dependencycheck.data.update.nvd.NvdCveInfo;
    +21  import static org.junit.Assert.assertEquals;
    +22  import org.junit.Test;
    +23  import org.owasp.dependencycheck.BaseTest;
    +24  
    +25  /**
    +26   * Rigorous test of setters/getters.
    +27   *
    +28   * @author Jeremy Long
    +29   */
    +30  public class NvdCveInfoTest extends BaseTest {
    +31  
    +32      /**
    +33       * Test of setId and getId method, of class NvdCveInfo.
    +34       */
    +35      @Test
    +36      public void testSetGetId() {
    +37          NvdCveInfo instance = new NvdCveInfo();
    +38          String expResult = "id";
    +39          instance.setId(expResult);
    +40          String result = instance.getId();
    +41          assertEquals(expResult, result);
    +42      }
    +43  
    +44      /**
    +45       * Test of getUrl method, of class NvdCveInfo.
    +46       */
    +47      @Test
    +48      public void testSetGetUrl() {
    +49          NvdCveInfo instance = new NvdCveInfo();
    +50          String expResult = "http://www.someurl.com/something";
    +51          instance.setUrl(expResult);
    +52          String result = instance.getUrl();
    +53          assertEquals(expResult, result);
    +54      }
    +55  
    +56      /**
    +57       * Test of getOldSchemaVersionUrl method, of class NvdCveInfo.
    +58       */
    +59      @Test
    +60      public void testSetGetOldSchemaVersionUrl() {
    +61          NvdCveInfo instance = new NvdCveInfo();
    +62          String expResult = "http://www.someurl.com/something";
    +63          instance.setOldSchemaVersionUrl(expResult);
    +64          String result = instance.getOldSchemaVersionUrl();
    +65          assertEquals(expResult, result);
    +66      }
    +67  
    +68      /**
    +69       * Test of getTimestamp method, of class NvdCveInfo.
    +70       */
    +71      @Test
    +72      public void testSetGetTimestamp() {
    +73          NvdCveInfo instance = new NvdCveInfo();
    +74          long expResult = 1337L;
    +75          instance.setTimestamp(expResult);
    +76          long result = instance.getTimestamp();
    +77          assertEquals(expResult, result);
    +78      }
    +79  
    +80      /**
    +81       * Test of getNeedsUpdate method, of class NvdCveInfo.
    +82       */
    +83      @Test
    +84      public void testSetGetNeedsUpdate() {
    +85          NvdCveInfo instance = new NvdCveInfo();
    +86          boolean expResult = true;
    +87          instance.setNeedsUpdate(expResult);
    +88          boolean result = instance.getNeedsUpdate();
    +89          assertEquals(expResult, result);
    +90      }
    +91  }
    +
    +
    + + + diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCveUpdaterIntegrationTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCveUpdaterIntegrationTest.html new file mode 100644 index 000000000..62b4001c4 --- /dev/null +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCveUpdaterIntegrationTest.html @@ -0,0 +1,82 @@ + + + +NvdCveUpdaterIntegrationTest 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.data.update.nvd;
    +19  
    +20  import java.io.File;
    +21  import java.util.Calendar;
    +22  import org.junit.Before;
    +23  import org.junit.Test;
    +24  import org.owasp.dependencycheck.BaseTest;
    +25  import org.owasp.dependencycheck.data.update.NvdCveUpdater;
    +26  import org.owasp.dependencycheck.utils.Settings;
    +27  
    +28  /**
    +29   *
    +30   * @author Jeremy Long
    +31   */
    +32  public class NvdCveUpdaterIntegrationTest extends BaseTest {
    +33  
    +34      @Before
    +35      public void setUp() throws Exception {
    +36          int year = Calendar.getInstance().get(Calendar.YEAR);
    +37          if (year <= 2014) {
    +38              //File f = new File(NvdCveUpdaterIntegrationTest.class.getClassLoader().getResource("nvdcve-2.0-2014.xml").getPath());
    +39              File f = BaseTest.getResourceAsFile(this, "nvdcve-2.0-2014.xml");
    +40              String baseURL = f.toURI().toURL().toString();
    +41              String modified12 = baseURL.replace("nvdcve-2.0-2014.xml", "nvdcve-modified.xml");
    +42              String modified20 = baseURL.replace("nvdcve-2.0-2014.xml", "nvdcve-2.0-modified.xml");
    +43              String full12 = baseURL.replace("nvdcve-2.0-2014.xml", "nvdcve-%d.xml");
    +44              String full20 = baseURL.replace("nvdcve-2.0-2014.xml", "nvdcve-2.0-%d.xml");
    +45  //        cve.url-1.2.modified=http://nvd.nist.gov/download/nvdcve-modified.xml
    +46  //        cve.url-2.0.modified=http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-modified.xml
    +47  //        cve.startyear=2014
    +48  //        cve.url-2.0.base=http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-%d.xml
    +49  //        cve.url-1.2.base=http://nvd.nist.gov/download/nvdcve-%d.xml
    +50  
    +51              Settings.setString(Settings.KEYS.CVE_MODIFIED_12_URL, modified12);
    +52              Settings.setString(Settings.KEYS.CVE_MODIFIED_20_URL, modified20);
    +53              Settings.setString(Settings.KEYS.CVE_SCHEMA_1_2, full12);
    +54              Settings.setString(Settings.KEYS.CVE_SCHEMA_2_0, full20);
    +55              Settings.setString(Settings.KEYS.CVE_START_YEAR, "2014");
    +56          } else {
    +57              System.err.println("Consider updating the local data files to make the NvdCveUpdaterIntegrationTest perform faster");
    +58          }
    +59      }
    +60  
    +61      /**
    +62       * Test of update method, of class NvdCveUpdater.
    +63       */
    +64      @Test
    +65      public void testUpdate() throws Exception {
    +66          NvdCveUpdater instance = new NvdCveUpdater();
    +67          instance.update();
    +68      }
    +69  }
    +
    +
    + + + 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 new file mode 100644 index 000000000..666a167a1 --- /dev/null +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCve_1_2_HandlerTest.html @@ -0,0 +1,86 @@ + + + +NvdCve_1_2_HandlerTest 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) 2012 Jeremy Long. All Rights Reserved.
    +17   */
    +18  package org.owasp.dependencycheck.data.update.nvd;
    +19  
    +20  import org.owasp.dependencycheck.data.update.nvd.NvdCve12Handler;
    +21  import java.io.File;
    +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_1_2_HandlerTest {
    +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  }
    +
    +
    + + + 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 new file mode 100644 index 000000000..9215102b2 --- /dev/null +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/NvdCve_2_0_HandlerTest.html @@ -0,0 +1,92 @@ + + + +NvdCve_2_0_HandlerTest 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) 2012 Jeremy Long. All Rights Reserved.
    +17   */
    +18  package org.owasp.dependencycheck.data.update.nvd;
    +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      }
    +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      }
    +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();
    +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  }
    +
    +
    + + + diff --git a/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/UpdateableNvdCveTest.html b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/UpdateableNvdCveTest.html new file mode 100644 index 000000000..6bfda62d9 --- /dev/null +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/UpdateableNvdCveTest.html @@ -0,0 +1,154 @@ + + + +UpdateableNvdCveTest 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.data.update.nvd;
    +19  
    +20  import org.owasp.dependencycheck.data.update.nvd.UpdateableNvdCve;
    +21  import org.owasp.dependencycheck.data.update.nvd.NvdCveInfo;
    +22  import java.io.File;
    +23  import java.io.IOException;
    +24  import java.net.MalformedURLException;
    +25  import static org.junit.Assert.assertEquals;
    +26  import static org.junit.Assert.assertFalse;
    +27  import static org.junit.Assert.assertTrue;
    +28  import org.junit.Test;
    +29  import org.owasp.dependencycheck.BaseTest;
    +30  import org.owasp.dependencycheck.utils.DownloadFailedException;
    +31  
    +32  /**
    +33   *
    +34   * @author Jeremy Long
    +35   */
    +36  public class UpdateableNvdCveTest extends BaseTest {
    +37  
    +38      /**
    +39       * Test of isUpdateNeeded method, of class UpdateableNvdCve.
    +40       */
    +41      @Test
    +42      public void testIsUpdateNeeded() throws MalformedURLException, DownloadFailedException, IOException {
    +43          String id = "key";
    +44          //use a local file as this test will load the result and check the timestamp
    +45          File f = new File("target/test-classes/nvdcve-2.0-2012.xml");
    +46          String url = "file:///" + f.getCanonicalPath();
    +47          UpdateableNvdCve instance = new UpdateableNvdCve();
    +48          instance.add(id, url, url, false);
    +49  
    +50          boolean expResult = false;
    +51          boolean result = instance.isUpdateNeeded();
    +52          assertEquals(expResult, result);
    +53  
    +54          instance.add("nextId", url, url, true);
    +55  
    +56          expResult = true;
    +57          result = instance.isUpdateNeeded();
    +58          assertEquals(expResult, result);
    +59      }
    +60  
    +61      /**
    +62       * Test of add method, of class UpdateableNvdCve.
    +63       */
    +64      @Test
    +65      public void testAdd_3args() throws Exception {
    +66          String id = "key";
    +67          File f = new File("target/test-classes/nvdcve-2.0-2012.xml");
    +68          //use a local file as this test will load the result and check the timestamp
    +69          String url = "file:///" + f.getCanonicalPath();
    +70          UpdateableNvdCve instance = new UpdateableNvdCve();
    +71          instance.add(id, url, url);
    +72          NvdCveInfo results = instance.get(id);
    +73          assertEquals(id, results.getId());
    +74          assertEquals(url, results.getUrl());
    +75          assertEquals(url, results.getOldSchemaVersionUrl());
    +76      }
    +77  
    +78      /**
    +79       * Test of add method, of class UpdateableNvdCve.
    +80       */
    +81      @Test
    +82      public void testAdd_4args() throws Exception {
    +83          String id = "key";
    +84          //use a local file as this test will load the result and check the timestamp
    +85          File f = new File("target/test-classes/nvdcve-2.0-2012.xml");
    +86          String url = "file:///" + f.getCanonicalPath();
    +87          UpdateableNvdCve instance = new UpdateableNvdCve();
    +88          instance.add(id, url, url, false);
    +89  
    +90          boolean expResult = false;
    +91          boolean result = instance.isUpdateNeeded();
    +92          assertEquals(expResult, result);
    +93  
    +94          instance.add("nextId", url, url, false);
    +95          NvdCveInfo results = instance.get(id);
    +96  
    +97          assertEquals(id, results.getId());
    +98          assertEquals(url, results.getUrl());
    +99          assertEquals(url, results.getOldSchemaVersionUrl());
    +100 
    +101     }
    +102 
    +103     /**
    +104      * Test of clear method, of class UpdateableNvdCve.
    +105      */
    +106     @Test
    +107     public void testClear() throws MalformedURLException, DownloadFailedException, IOException {
    +108         String id = "key";
    +109         //use a local file as this test will load the result and check the timestamp
    +110         File f = new File("target/test-classes/nvdcve-2.0-2012.xml");
    +111         String url = "file:///" + f.getCanonicalPath();
    +112         UpdateableNvdCve instance = new UpdateableNvdCve();
    +113         instance.add(id, url, url, false);
    +114         assertFalse(instance.getCollection().isEmpty());
    +115         instance.clear();
    +116         assertTrue(instance.getCollection().isEmpty());
    +117     }
    +118 
    +119     /**
    +120      * Test of iterator method, of class UpdatableNvdCve.
    +121      */
    +122     @Test
    +123     public void testIterator() throws IOException {
    +124         //use a local file as this test will load the result and check the timestamp
    +125         File f = new File("target/test-classes/nvdcve-2.0-2012.xml");
    +126         String url = "file:///" + f.getCanonicalPath();
    +127         UpdateableNvdCve instance = new UpdateableNvdCve();
    +128         instance.add("one", url, url, false);
    +129         instance.add("two", url, url, false);
    +130         instance.add("three", url, url, false);
    +131         int itemsProcessed = 0;
    +132         for (NvdCveInfo item : instance) {
    +133             if ("one".equals(item.getId())) {
    +134                 instance.remove();
    +135             }
    +136             itemsProcessed += 1;
    +137         }
    +138         assertEquals(3, itemsProcessed);
    +139         assertEquals(2, instance.getCollection().size());
    +140     }
    +141 }
    +
    +
    + + + 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 new file mode 100644 index 000000000..158e41b78 --- /dev/null +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/package-frame.html @@ -0,0 +1,39 @@ + + + + + + Dependency-Check Core 1.3.0 Reference Package org.owasp.dependencycheck.data.update.nvd + + + + +

    + org.owasp.dependencycheck.data.update.nvd +

    + +

    Classes

    + + + + + \ No newline at end of file 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 new file mode 100644 index 000000000..66f743979 --- /dev/null +++ b/dependency-check-core/xref-test/org/owasp/dependencycheck/data/update/nvd/package-summary.html @@ -0,0 +1,94 @@ + + + + + + Dependency-Check Core 1.3.0 Reference Package org.owasp.dependencycheck.data.update.nvd + + + +
    + +
    +
    + +
    + +

    Package org.owasp.dependencycheck.data.update.nvd

    + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Class Summary
    + DownloadTaskTest +
    + NvdCveInfoTest +
    + NvdCveUpdaterIntegrationTest +
    + NvdCve_1_2_HandlerTest +
    + NvdCve_2_0_HandlerTest +
    + UpdateableNvdCveTest +
    + +
    + +
    +
    + +
    +
    + + + \ No newline at end of file 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 487dac001..b9ac9a36b 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.2.11 Reference Package org.owasp.dependencycheck.data.update + Dependency-Check Core 1.3.0 Reference Package org.owasp.dependencycheck.data.update @@ -16,19 +16,19 @@ 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 7fd88f4e9..0dc62b971 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.2.11 Reference Package org.owasp.dependencycheck.data.update + Dependency-Check Core 1.3.0 Reference Package org.owasp.dependencycheck.data.update @@ -36,29 +36,29 @@ + + BaseUpdaterImpl + + + + + BaseUpdaterTest + + + + + CpeUpdaterIntegrationTest + + + EngineVersionCheckTest - - - - NvdCveInfoTest - NvdCveUpdaterIntegrationTest - - - - StandardUpdateIntegrationTest - - - - - UpdateableNvdCveTest - 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 6d0a8048b..f29864b61 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 @@ -94,253 +94,232 @@ 86 public void testSetActualFilePath() { 87 String actualFilePath = "file.tar"; 88 Dependency instance = new Dependency(); -89 instance.setActualFilePath(actualFilePath); -90 assertEquals(actualFilePath, instance.getActualFilePath()); -91 } -92 -93 /** -94 * Test of getActualFilePath method, of class Dependency. -95 */ -96 @Test -97 public void testGetActualFilePath() { -98 Dependency instance = new Dependency(); -99 String expResult = "file.tar"; -100 instance.setActualFilePath(expResult); -101 String result = instance.getActualFilePath(); -102 assertEquals(expResult, result); -103 } -104 -105 /** -106 * Test of setFilePath method, of class Dependency. -107 */ -108 @Test -109 public void testSetFilePath() { -110 String filePath = "file.tar"; -111 Dependency instance = new Dependency(); -112 instance.setFilePath(filePath); -113 assertEquals(filePath, instance.getFilePath()); -114 } -115 -116 /** -117 * Test of getFilePath method, of class Dependency. -118 */ -119 @Test -120 public void testGetFilePath() { -121 Dependency instance = new Dependency(); -122 String expResult = "file.tar"; -123 instance.setFilePath(expResult); -124 String result = instance.getFilePath(); -125 assertEquals(expResult, result); -126 } -127 -128 /** -129 * Test of setFileExtension method, of class Dependency. -130 */ -131 @Test -132 public void testSetFileExtension() { -133 String fileExtension = "jar"; -134 Dependency instance = new Dependency(); -135 instance.setFileExtension(fileExtension); -136 assertEquals(fileExtension, instance.getFileExtension()); -137 } -138 -139 /** -140 * Test of getFileExtension method, of class Dependency. -141 */ -142 @Test -143 public void testGetFileExtension() { -144 Dependency instance = new Dependency(); -145 String expResult = "jar"; -146 instance.setFileExtension(expResult); -147 String result = instance.getFileExtension(); -148 assertEquals(expResult, result); -149 } -150 -151 /** -152 * Test of getMd5sum method, of class Dependency. -153 */ -154 @Test -155 public void testGetMd5sum() { -156 //File file = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath()); -157 File file = BaseTest.getResourceAsFile(this, "struts2-core-2.1.2.jar"); -158 -159 Dependency instance = new Dependency(file); -160 //assertEquals("89CE9E36AA9A9E03F1450936D2F4F8DD0F961F8B", result.getSha1sum()); -161 //String expResult = "C30B57142E1CCBC1EFD5CD15F307358F"; -162 String expResult = "c30b57142e1ccbc1efd5cd15f307358f"; -163 String result = instance.getMd5sum(); -164 assertEquals(expResult, result); -165 } -166 -167 /** -168 * Test of setMd5sum method, of class Dependency. -169 */ -170 @Test -171 public void testSetMd5sum() { -172 String md5sum = "test"; -173 Dependency instance = new Dependency(); -174 instance.setMd5sum(md5sum); -175 assertEquals(md5sum, instance.getMd5sum()); -176 } -177 -178 /** -179 * Test of getSha1sum method, of class Dependency. -180 */ -181 @Test -182 public void testGetSha1sum() { -183 //File file = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath()); -184 File file = BaseTest.getResourceAsFile(this, "struts2-core-2.1.2.jar"); -185 Dependency instance = new Dependency(file); -186 //String expResult = "89CE9E36AA9A9E03F1450936D2F4F8DD0F961F8B"; -187 String expResult = "89ce9e36aa9a9e03f1450936d2f4f8dd0f961f8b"; -188 String result = instance.getSha1sum(); -189 assertEquals(expResult, result); -190 } -191 -192 /** -193 * Test of setSha1sum method, of class Dependency. -194 */ -195 @Test -196 public void testSetSha1sum() { -197 String sha1sum = "test"; -198 Dependency instance = new Dependency(); -199 instance.setSha1sum(sha1sum); -200 assertEquals(sha1sum, instance.getSha1sum()); -201 } -202 -203 /** -204 * Test of getIdentifiers method, of class Dependency. -205 */ -206 @Test -207 public void testGetIdentifiers() { -208 Dependency instance = new Dependency(); -209 List expResult = null; -210 Set<Identifier> result = instance.getIdentifiers(); -211 -212 assertTrue(true); //this is just a getter setter pair. -213 } +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"); +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 } +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 List expResult = null; +189 Set<Identifier> result = instance.getIdentifiers(); +190 +191 assertTrue(true); //this is just a getter setter pair. +192 } +193 +194 /** +195 * Test of setIdentifiers method, of class Dependency. +196 */ +197 @Test +198 public void testSetIdentifiers() { +199 Set<Identifier> identifiers = null; +200 Dependency instance = new Dependency(); +201 instance.setIdentifiers(identifiers); +202 assertTrue(true); //this is just a getter setter pair. +203 } +204 +205 /** +206 * Test of addIdentifier method, of class Dependency. +207 */ +208 @Test +209 public void testAddIdentifier() { +210 String type = "cpe"; +211 String value = "cpe:/a:apache:struts:2.1.2"; +212 String url = "http://somewhere"; +213 Identifier expResult = new Identifier(type, value, url); 214 -215 /** -216 * Test of setIdentifiers method, of class Dependency. -217 */ -218 @Test -219 public void testSetIdentifiers() { -220 Set<Identifier> identifiers = null; -221 Dependency instance = new Dependency(); -222 instance.setIdentifiers(identifiers); -223 assertTrue(true); //this is just a getter setter pair. -224 } -225 -226 /** -227 * Test of addIdentifier method, of class Dependency. -228 */ -229 @Test -230 public void testAddIdentifier() { -231 String type = "cpe"; -232 String value = "cpe:/a:apache:struts:2.1.2"; -233 String url = "http://somewhere"; -234 Identifier expResult = new Identifier(type, value, url); -235 -236 Dependency instance = new Dependency(); -237 instance.addIdentifier(type, value, url); -238 assertEquals(1, instance.getIdentifiers().size()); -239 assertTrue("Identifier doesn't contain expected result.", instance.getIdentifiers().contains(expResult)); -240 } -241 -242 /** -243 * Test of getEvidence method, of class Dependency. -244 */ -245 @Test -246 public void testGetEvidence() { -247 Dependency instance = new Dependency(); -248 EvidenceCollection expResult = null; -249 EvidenceCollection result = instance.getEvidence(); -250 assertTrue(true); //this is just a getter setter pair. -251 } -252 -253 /** -254 * Test of getEvidenceUsed method, of class Dependency. -255 */ -256 @Test -257 public void testGetEvidenceUsed() { -258 Dependency instance = new Dependency(); -259 String expResult = "used"; -260 -261 instance.getProductEvidence().addEvidence("used", "used", "used", Confidence.HIGH); -262 instance.getProductEvidence().addEvidence("not", "not", "not", Confidence.MEDIUM); -263 for (Evidence e : instance.getProductEvidence().iterator(Confidence.HIGH)) { -264 String use = e.getValue(); -265 } -266 -267 EvidenceCollection result = instance.getEvidenceUsed(); -268 -269 assertEquals(1, result.size()); -270 assertTrue(result.containsUsedString(expResult)); -271 } -272 -273 /** -274 * Test of getVendorEvidence method, of class Dependency. -275 */ -276 @Test -277 public void testGetVendorEvidence() { -278 Dependency instance = new Dependency(); -279 EvidenceCollection expResult = null; -280 EvidenceCollection result = instance.getVendorEvidence(); -281 assertTrue(true); //this is just a getter setter pair. -282 } -283 -284 /** -285 * Test of getProductEvidence method, of class Dependency. -286 */ -287 @Test -288 public void testGetProductEvidence() { -289 Dependency instance = new Dependency(); -290 EvidenceCollection expResult = null; -291 EvidenceCollection result = instance.getProductEvidence(); -292 assertTrue(true); //this is just a getter setter pair. -293 } -294 -295 /** -296 * Test of getVersionEvidence method, of class Dependency. -297 */ -298 @Test -299 public void testGetVersionEvidence() { -300 Dependency instance = new Dependency(); -301 EvidenceCollection expResult = null; -302 EvidenceCollection result = instance.getVersionEvidence(); -303 assertTrue(true); //this is just a getter setter pair. -304 } -305 -306 /** -307 * Test of addAsEvidence method, of class Dependency. -308 */ -309 @Test -310 public void testAddAsEvidence() { -311 Dependency instance = new Dependency(); -312 MavenArtifact mavenArtifact = new MavenArtifact("group", "artifact", "version", "url"); -313 instance.addAsEvidence("pom", mavenArtifact, Confidence.HIGH); -314 assertTrue(instance.getEvidence().contains(Confidence.HIGH)); -315 assertFalse(instance.getEvidence().getEvidence("pom", "groupid").isEmpty()); -316 assertFalse(instance.getEvidence().getEvidence("pom", "artifactid").isEmpty()); -317 assertFalse(instance.getEvidence().getEvidence("pom", "version").isEmpty()); -318 assertFalse(instance.getIdentifiers().isEmpty()); -319 } -320 -321 /** -322 * Test of addAsEvidence method, of class Dependency. -323 */ -324 @Test -325 public void testAddAsEvidenceWithEmptyArtefact() { -326 Dependency instance = new Dependency(); -327 MavenArtifact mavenArtifact = new MavenArtifact(null, null, null, null); -328 instance.addAsEvidence("pom", mavenArtifact, Confidence.HIGH); -329 assertFalse(instance.getEvidence().contains(Confidence.HIGH)); -330 assertTrue(instance.getEvidence().getEvidence("pom", "groupid").isEmpty()); -331 assertTrue(instance.getEvidence().getEvidence("pom", "artifactid").isEmpty()); -332 assertTrue(instance.getEvidence().getEvidence("pom", "version").isEmpty()); -333 assertTrue(instance.getIdentifiers().isEmpty()); -334 } -335 } +215 Dependency instance = new Dependency(); +216 instance.addIdentifier(type, value, url); +217 assertEquals(1, instance.getIdentifiers().size()); +218 assertTrue("Identifier doesn't contain expected result.", instance.getIdentifiers().contains(expResult)); +219 } +220 +221 /** +222 * Test of getEvidence method, of class Dependency. +223 */ +224 @Test +225 public void testGetEvidence() { +226 Dependency instance = new Dependency(); +227 EvidenceCollection expResult = null; +228 EvidenceCollection result = instance.getEvidence(); +229 assertTrue(true); //this is just a getter setter pair. +230 } +231 +232 /** +233 * Test of getEvidenceUsed method, of class Dependency. +234 */ +235 @Test +236 public void testGetEvidenceUsed() { +237 Dependency instance = new Dependency(); +238 String expResult = "used"; +239 +240 instance.getProductEvidence().addEvidence("used", "used", "used", Confidence.HIGH); +241 instance.getProductEvidence().addEvidence("not", "not", "not", Confidence.MEDIUM); +242 for (Evidence e : instance.getProductEvidence().iterator(Confidence.HIGH)) { +243 String use = e.getValue(); +244 } +245 +246 EvidenceCollection result = instance.getEvidenceUsed(); +247 +248 assertEquals(1, result.size()); +249 assertTrue(result.containsUsedString(expResult)); +250 } +251 +252 /** +253 * Test of getVendorEvidence method, of class Dependency. +254 */ +255 @Test +256 public void testGetVendorEvidence() { +257 Dependency instance = new Dependency(); +258 EvidenceCollection expResult = null; +259 EvidenceCollection result = instance.getVendorEvidence(); +260 assertTrue(true); //this is just a getter setter pair. +261 } +262 +263 /** +264 * Test of getProductEvidence method, of class Dependency. +265 */ +266 @Test +267 public void testGetProductEvidence() { +268 Dependency instance = new Dependency(); +269 EvidenceCollection expResult = null; +270 EvidenceCollection result = instance.getProductEvidence(); +271 assertTrue(true); //this is just a getter setter pair. +272 } +273 +274 /** +275 * Test of getVersionEvidence method, of class Dependency. +276 */ +277 @Test +278 public void testGetVersionEvidence() { +279 Dependency instance = new Dependency(); +280 EvidenceCollection expResult = null; +281 EvidenceCollection result = instance.getVersionEvidence(); +282 assertTrue(true); //this is just a getter setter pair. +283 } +284 +285 /** +286 * Test of addAsEvidence method, of class Dependency. +287 */ +288 @Test +289 public void testAddAsEvidence() { +290 Dependency instance = new Dependency(); +291 MavenArtifact mavenArtifact = new MavenArtifact("group", "artifact", "version", "url"); +292 instance.addAsEvidence("pom", mavenArtifact, Confidence.HIGH); +293 assertTrue(instance.getEvidence().contains(Confidence.HIGH)); +294 assertFalse(instance.getEvidence().getEvidence("pom", "groupid").isEmpty()); +295 assertFalse(instance.getEvidence().getEvidence("pom", "artifactid").isEmpty()); +296 assertFalse(instance.getEvidence().getEvidence("pom", "version").isEmpty()); +297 assertFalse(instance.getIdentifiers().isEmpty()); +298 } +299 +300 /** +301 * Test of addAsEvidence method, of class Dependency. +302 */ +303 @Test +304 public void testAddAsEvidenceWithEmptyArtefact() { +305 Dependency instance = new Dependency(); +306 MavenArtifact mavenArtifact = new MavenArtifact(null, null, null, null); +307 instance.addAsEvidence("pom", mavenArtifact, Confidence.HIGH); +308 assertFalse(instance.getEvidence().contains(Confidence.HIGH)); +309 assertTrue(instance.getEvidence().getEvidence("pom", "groupid").isEmpty()); +310 assertTrue(instance.getEvidence().getEvidence("pom", "artifactid").isEmpty()); +311 assertTrue(instance.getEvidence().getEvidence("pom", "version").isEmpty()); +312 assertTrue(instance.getIdentifiers().isEmpty()); +313 } +314 }
    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 bbe0f39b8..b11464cc1 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 @@ -27,90 +27,99 @@ 19 20 import org.junit.Test; 21 import static org.junit.Assert.*; -22 -23 /** -24 * -25 * @author Jeremy Long -26 */ -27 public class EvidenceTest { -28 -29 /** -30 * Test of equals method, of class Evidence. -31 */ -32 @Test -33 public void testEquals() { -34 Evidence that0 = new Evidence("file", "name", "guice-3.0", Confidence.HIGHEST); -35 Evidence that1 = new Evidence("jar", "package name", "dependency", Confidence.HIGHEST); -36 Evidence that2 = new Evidence("jar", "package name", "google", Confidence.HIGHEST); -37 Evidence that3 = new Evidence("jar", "package name", "guice", Confidence.HIGHEST); -38 Evidence that4 = new Evidence("jar", "package name", "inject", Confidence.HIGHEST); -39 Evidence that5 = new Evidence("jar", "package name", "inject", Confidence.LOW); -40 Evidence that6 = new Evidence("jar", "package name", "internal", Confidence.LOW); -41 Evidence that7 = new Evidence("manifest", "Bundle-Description", "Guice is a lightweight dependency injection framework for Java 5 and above", Confidence.MEDIUM); -42 Evidence that8 = new Evidence("Manifest", "Implementation-Title", "Spring Framework", Confidence.HIGH); -43 -44 Evidence instance = new Evidence("Manifest", "Implementation-Title", "Spring Framework", Confidence.HIGH); -45 assertFalse(instance.equals(that0)); -46 assertFalse(instance.equals(that1)); -47 assertFalse(instance.equals(that2)); -48 assertFalse(instance.equals(that3)); -49 assertFalse(instance.equals(that4)); -50 assertFalse(instance.equals(that5)); -51 assertFalse(instance.equals(that6)); -52 assertFalse(instance.equals(that7)); -53 assertTrue(instance.equals(that8)); -54 } -55 -56 /** -57 * Test of compareTo method, of class Evidence. -58 */ -59 @Test -60 public void testCompareTo() { -61 Evidence that0 = new Evidence("file", "name", "guice-3.0", Confidence.HIGHEST); -62 Evidence that1 = new Evidence("jar", "package name", "dependency", Confidence.HIGHEST); -63 Evidence that2 = new Evidence("jar", "package name", "google", Confidence.HIGHEST); -64 Evidence that3 = new Evidence("jar", "package name", "guice", Confidence.HIGHEST); -65 Evidence that4 = new Evidence("jar", "package name", "inject", Confidence.HIGHEST); -66 Evidence that5 = new Evidence("jar", "package name", "inject", Confidence.LOW); -67 Evidence that6 = new Evidence("jar", "package name", "internal", Confidence.LOW); -68 Evidence that7 = new Evidence("manifest", "Bundle-Description", "Guice is a lightweight dependency injection framework for Java 5 and above", Confidence.MEDIUM); -69 Evidence that8 = new Evidence("Manifest", "Implementation-Title", "Spring Framework", Confidence.HIGH); -70 -71 Evidence that9 = new Evidence("manifest", "implementation-title", "zippy", Confidence.HIGH); -72 -73 Evidence instance = new Evidence("Manifest", "Implementation-Title", "Spring Framework", Confidence.HIGH); -74 -75 int result = instance.compareTo(that0); -76 assertTrue(result > 0); -77 -78 result = instance.compareTo(that1); -79 assertTrue(result > 0); -80 -81 result = instance.compareTo(that2); -82 assertTrue(result > 0); +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 result = instance.compareTo(that3); +84 int result = instance.compareTo(that0); 85 assertTrue(result > 0); 86 -87 result = instance.compareTo(that4); +87 result = instance.compareTo(that1); 88 assertTrue(result > 0); 89 -90 result = instance.compareTo(that5); +90 result = instance.compareTo(that2); 91 assertTrue(result > 0); 92 -93 result = instance.compareTo(that6); +93 result = instance.compareTo(that3); 94 assertTrue(result > 0); 95 -96 result = instance.compareTo(that7); +96 result = instance.compareTo(that4); 97 assertTrue(result > 0); 98 -99 result = instance.compareTo(that8); -100 assertTrue(result == 0); +99 result = instance.compareTo(that5); +100 assertTrue(result > 0); 101 -102 result = instance.compareTo(that9); -103 assertTrue(result < 0); -104 } -105 } +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 }
    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 33afc10b5..50478956c 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.2.11 Reference Package org.owasp.dependencycheck.dependency + Dependency-Check Core 1.3.0 Reference Package org.owasp.dependencycheck.dependency 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 65cbeb3e8..9ca867445 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.2.11 Reference Package org.owasp.dependencycheck.dependency + Dependency-Check Core 1.3.0 Reference Package org.owasp.dependencycheck.dependency 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 9a9c2addf..f93fefcd0 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.2.11 Reference Package org.owasp.dependencycheck + Dependency-Check Core 1.3.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 7a4b11583..bced1de2a 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.2.11 Reference Package org.owasp.dependencycheck + Dependency-Check Core 1.3.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 b28f66f60..bcbdf2277 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 @@ -155,7 +155,7 @@ 147 148 engine.cleanup(); 149 -150 InputStream xsdStream = ReportGenerator.class.getClassLoader().getResourceAsStream("schema/DependencyCheck.xsd"); +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); 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 74f2ca19d..69c8a9afe 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.2.11 Reference Package org.owasp.dependencycheck.reporting + Dependency-Check Core 1.3.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 b5ef7f335..c3c12477d 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.2.11 Reference Package org.owasp.dependencycheck.reporting + Dependency-Check Core 1.3.0 Reference Package org.owasp.dependencycheck.reporting 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 2c43c6e90..44f20f803 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.2.11 Reference Package org.owasp.dependencycheck.suppression + Dependency-Check Core 1.3.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 dd96632ca..3d14480e6 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.2.11 Reference Package org.owasp.dependencycheck.suppression + Dependency-Check Core 1.3.0 Reference Package org.owasp.dependencycheck.suppression 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 c9e7a95d2..6f91a2d4c 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.2.11 Reference Package org.owasp.dependencycheck.utils + Dependency-Check Core 1.3.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 a82e6e0fa..996a2dced 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.2.11 Reference Package org.owasp.dependencycheck.utils + Dependency-Check Core 1.3.0 Reference Package org.owasp.dependencycheck.utils 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 71ac633c1..a705b6579 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.2.11 Reference Package org.owasp.dependencycheck.xml.pom + Dependency-Check Core 1.3.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 3a8d7f017..1160369e7 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.2.11 Reference Package org.owasp.dependencycheck.xml.pom + Dependency-Check Core 1.3.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 3ffa71090..5ca72c9f3 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.2.11 Reference + Dependency-Check Core 1.3.0 Reference @@ -46,10 +46,7 @@ org.owasp.dependencycheck.data.update
  • - org.owasp.dependencycheck.data.update.task -
  • -
  • - org.owasp.dependencycheck.data.update.xml + org.owasp.dependencycheck.data.update.nvd
  • org.owasp.dependencycheck.dependency diff --git a/dependency-check-core/xref-test/overview-summary.html b/dependency-check-core/xref-test/overview-summary.html index 7b5bf6fb6..f7cbbbce3 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.2.11 Reference + Dependency-Check Core 1.3.0 Reference @@ -24,7 +24,7 @@ -

    Dependency-Check Core 1.2.11 Reference

    +

    Dependency-Check Core 1.3.0 Reference

    @@ -85,12 +85,7 @@ - - - diff --git a/dependency-check-core/xref/allclasses-frame.html b/dependency-check-core/xref/allclasses-frame.html index 383133ff2..01548d678 100644 --- a/dependency-check-core/xref/allclasses-frame.html +++ b/dependency-check-core/xref/allclasses-frame.html @@ -46,9 +46,21 @@
  • AssemblyAnalyzer +
  • +
  • + AutoconfAnalyzer +
  • +
  • + BaseUpdater +
  • +
  • + CMakeAnalyzer
  • CPEAnalyzer +
  • +
  • + CPEHandler
  • CachedWebDataSource @@ -70,12 +82,18 @@
  • CorruptDatabaseException +
  • +
  • + Cpe
  • CpeMemoryIndex
  • CpeSuppressionAnalyzer +
  • +
  • + CpeUpdater
  • CveDB @@ -117,7 +135,7 @@ DependencyVersionUtil
  • - DownloadTask + DownloadTask
  • DriverLoadException @@ -129,7 +147,7 @@ DriverShim
  • - Element + Element
  • Engine @@ -157,6 +175,9 @@
  • Fields +
  • +
  • + FileFilterBuilder
  • FileNameAnalyzer @@ -196,9 +217,6 @@
  • JarAnalyzer -
  • -
  • - JavaScriptAnalyzer
  • License @@ -237,19 +255,22 @@ NuspecParser
  • - NvdCve12Handler + NvdCve12Handler
  • - NvdCve20Handler + NvdCve20Handler
  • NvdCveAnalyzer
  • - NvdCveInfo + NvdCveInfo
  • NvdCveUpdater +
  • +
  • + OpenSSLAnalyzer
  • Pair @@ -267,7 +288,7 @@ PomUtils
  • - ProcessTask + ProcessTask
  • PropertyType @@ -289,9 +310,6 @@
  • SearchFieldAnalyzer -
  • -
  • - StandardUpdate
  • SuppressionErrorHandler @@ -318,7 +336,7 @@ UpdateService
  • - UpdateableNvdCve + UpdateableNvdCve
  • UrlStringUtils diff --git a/dependency-check-core/xref/index.html b/dependency-check-core/xref/index.html index 197fb6e15..a5edb35ba 100644 --- a/dependency-check-core/xref/index.html +++ b/dependency-check-core/xref/index.html @@ -4,7 +4,7 @@ - Dependency-Check Core 1.2.11 Reference + Dependency-Check Core 1.3.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 198b29702..58ee0ce1a 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/Engine.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/Engine.html @@ -25,157 +25,157 @@ 17 */ 18 package org.owasp.dependencycheck; 19 -20 import java.io.File; -21 import java.util.ArrayList; -22 import java.util.EnumMap; -23 import java.util.HashSet; -24 import java.util.Iterator; -25 import java.util.List; -26 import java.util.Set; -27 import java.util.logging.Level; -28 import java.util.logging.Logger; -29 import org.owasp.dependencycheck.analyzer.AnalysisPhase; -30 import org.owasp.dependencycheck.analyzer.Analyzer; -31 import org.owasp.dependencycheck.analyzer.AnalyzerService; -32 import org.owasp.dependencycheck.analyzer.FileTypeAnalyzer; -33 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; -34 import org.owasp.dependencycheck.data.nvdcve.ConnectionFactory; -35 import org.owasp.dependencycheck.data.nvdcve.CveDB; -36 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; -37 import org.owasp.dependencycheck.data.update.CachedWebDataSource; -38 import org.owasp.dependencycheck.data.update.UpdateService; -39 import org.owasp.dependencycheck.data.update.exception.UpdateException; -40 import org.owasp.dependencycheck.dependency.Dependency; -41 import org.owasp.dependencycheck.exception.NoDataException; -42 import org.owasp.dependencycheck.utils.FileUtils; -43 import org.owasp.dependencycheck.utils.InvalidSettingException; -44 import org.owasp.dependencycheck.utils.Settings; -45 -46 /** -47 * Scans files, directories, etc. for Dependencies. Analyzers are loaded and used to process the files found by the scan, if a -48 * file is encountered and an Analyzer is associated with the file type then the file is turned into a dependency. -49 * -50 * @author Jeremy Long -51 */ -52 public class Engine { -53 -54 /** -55 * The list of dependencies. -56 */ -57 private List<Dependency> dependencies = new ArrayList<Dependency>(); -58 /** -59 * A Map of analyzers grouped by Analysis phase. -60 */ -61 private EnumMap<AnalysisPhase, List<Analyzer>> analyzers = new EnumMap<AnalysisPhase, List<Analyzer>>(AnalysisPhase.class); -62 -63 /** -64 * A Map of analyzers grouped by Analysis phase. -65 */ -66 private Set<FileTypeAnalyzer> fileTypeAnalyzers = new HashSet<FileTypeAnalyzer>(); -67 -68 /** -69 * The ClassLoader to use when dynamically loading Analyzer and Update services. -70 */ -71 private ClassLoader serviceClassLoader = Thread.currentThread().getContextClassLoader(); -72 /** -73 * The Logger for use throughout the class. -74 */ -75 private static final Logger LOGGER = Logger.getLogger(Engine.class.getName()); -76 -77 /** -78 * Creates a new Engine. -79 * -80 * @throws DatabaseException thrown if there is an error connecting to the database -81 */ -82 public Engine() throws DatabaseException { -83 initializeEngine(); -84 } -85 -86 /** -87 * Creates a new Engine. -88 * -89 * @param serviceClassLoader a reference the class loader being used -90 * @throws DatabaseException thrown if there is an error connecting to the database -91 */ -92 public Engine(ClassLoader serviceClassLoader) throws DatabaseException { -93 this.serviceClassLoader = serviceClassLoader; -94 initializeEngine(); -95 } -96 -97 /** -98 * Creates a new Engine using the specified classloader to dynamically load Analyzer and Update services. -99 * -100 * @throws DatabaseException thrown if there is an error connecting to the database -101 */ -102 protected final void initializeEngine() throws DatabaseException { -103 ConnectionFactory.initialize(); -104 loadAnalyzers(); -105 } -106 -107 /** -108 * Properly cleans up resources allocated during analysis. -109 */ -110 public void cleanup() { -111 ConnectionFactory.cleanup(); -112 } -113 -114 /** -115 * Loads the analyzers specified in the configuration file (or system properties). -116 */ -117 private void loadAnalyzers() { -118 if (!analyzers.isEmpty()) { -119 return; -120 } -121 for (AnalysisPhase phase : AnalysisPhase.values()) { -122 analyzers.put(phase, new ArrayList<Analyzer>()); -123 } -124 -125 final AnalyzerService service = new AnalyzerService(serviceClassLoader); -126 final Iterator<Analyzer> iterator = service.getAnalyzers(); -127 while (iterator.hasNext()) { -128 final Analyzer a = iterator.next(); -129 analyzers.get(a.getAnalysisPhase()).add(a); -130 if (a instanceof FileTypeAnalyzer) { -131 this.fileTypeAnalyzers.add((FileTypeAnalyzer) a); -132 } -133 } -134 } -135 -136 /** -137 * Get the List of the analyzers for a specific phase of analysis. -138 * -139 * @param phase the phase to get the configured analyzers. -140 * @return the analyzers loaded -141 */ -142 public List<Analyzer> getAnalyzers(AnalysisPhase phase) { -143 return analyzers.get(phase); -144 } -145 -146 /** -147 * Get the dependencies identified. -148 * -149 * @return the dependencies identified -150 */ -151 public List<Dependency> getDependencies() { -152 return dependencies; -153 } -154 -155 /** -156 * Sets the dependencies. -157 * -158 * @param dependencies the dependencies -159 */ -160 public void setDependencies(List<Dependency> dependencies) { -161 this.dependencies = dependencies; -162 } -163 -164 /** -165 * Scans an array of files or directories. If a directory is specified, it will be scanned recursively. Any dependencies -166 * identified are added to the dependency collection. -167 * -168 * @param paths an array of paths to files or directories to be analyzed -169 * @return the list of dependencies scanned -170 * +20 import org.owasp.dependencycheck.analyzer.AnalysisPhase; +21 import org.owasp.dependencycheck.analyzer.Analyzer; +22 import org.owasp.dependencycheck.analyzer.AnalyzerService; +23 import org.owasp.dependencycheck.analyzer.FileTypeAnalyzer; +24 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; +25 import org.owasp.dependencycheck.data.nvdcve.ConnectionFactory; +26 import org.owasp.dependencycheck.data.nvdcve.CveDB; +27 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; +28 import org.owasp.dependencycheck.data.update.CachedWebDataSource; +29 import org.owasp.dependencycheck.data.update.UpdateService; +30 import org.owasp.dependencycheck.data.update.exception.UpdateException; +31 import org.owasp.dependencycheck.dependency.Dependency; +32 import org.owasp.dependencycheck.exception.NoDataException; +33 import org.owasp.dependencycheck.utils.InvalidSettingException; +34 import org.owasp.dependencycheck.utils.Settings; +35 import org.slf4j.Logger; +36 import org.slf4j.LoggerFactory; +37 +38 import java.io.File; +39 import java.io.FileFilter; +40 import java.util.ArrayList; +41 import java.util.EnumMap; +42 import java.util.HashSet; +43 import java.util.Iterator; +44 import java.util.List; +45 import java.util.Set; +46 +47 /** +48 * Scans files, directories, etc. for Dependencies. Analyzers are loaded and used to process the files found by the scan, if a +49 * file is encountered and an Analyzer is associated with the file type then the file is turned into a dependency. +50 * +51 * @author Jeremy Long +52 */ +53 public class Engine implements FileFilter { +54 +55 /** +56 * The list of dependencies. +57 */ +58 private List<Dependency> dependencies = new ArrayList<Dependency>(); +59 /** +60 * A Map of analyzers grouped by Analysis phase. +61 */ +62 private EnumMap<AnalysisPhase, List<Analyzer>> analyzers = new EnumMap<AnalysisPhase, List<Analyzer>>(AnalysisPhase.class); +63 +64 /** +65 * A Map of analyzers grouped by Analysis phase. +66 */ +67 private Set<FileTypeAnalyzer> fileTypeAnalyzers = new HashSet<FileTypeAnalyzer>(); +68 +69 /** +70 * The ClassLoader to use when dynamically loading Analyzer and Update services. +71 */ +72 private ClassLoader serviceClassLoader = Thread.currentThread().getContextClassLoader(); +73 /** +74 * The Logger for use throughout the class. +75 */ +76 private static final Logger LOGGER = LoggerFactory.getLogger(Engine.class); +77 +78 /** +79 * Creates a new Engine. +80 * +81 * @throws DatabaseException thrown if there is an error connecting to the database +82 */ +83 public Engine() throws DatabaseException { +84 initializeEngine(); +85 } +86 +87 /** +88 * Creates a new Engine. +89 * +90 * @param serviceClassLoader a reference the class loader being used +91 * @throws DatabaseException thrown if there is an error connecting to the database +92 */ +93 public Engine(ClassLoader serviceClassLoader) throws DatabaseException { +94 this.serviceClassLoader = serviceClassLoader; +95 initializeEngine(); +96 } +97 +98 /** +99 * Creates a new Engine using the specified classloader to dynamically load Analyzer and Update services. +100 * +101 * @throws DatabaseException thrown if there is an error connecting to the database +102 */ +103 protected final void initializeEngine() throws DatabaseException { +104 ConnectionFactory.initialize(); +105 loadAnalyzers(); +106 } +107 +108 /** +109 * Properly cleans up resources allocated during analysis. +110 */ +111 public void cleanup() { +112 ConnectionFactory.cleanup(); +113 } +114 +115 /** +116 * Loads the analyzers specified in the configuration file (or system properties). +117 */ +118 private void loadAnalyzers() { +119 if (!analyzers.isEmpty()) { +120 return; +121 } +122 for (AnalysisPhase phase : AnalysisPhase.values()) { +123 analyzers.put(phase, new ArrayList<Analyzer>()); +124 } +125 +126 final AnalyzerService service = new AnalyzerService(serviceClassLoader); +127 final Iterator<Analyzer> iterator = service.getAnalyzers(); +128 while (iterator.hasNext()) { +129 final Analyzer a = iterator.next(); +130 analyzers.get(a.getAnalysisPhase()).add(a); +131 if (a instanceof FileTypeAnalyzer) { +132 this.fileTypeAnalyzers.add((FileTypeAnalyzer) a); +133 } +134 } +135 } +136 +137 /** +138 * Get the List of the analyzers for a specific phase of analysis. +139 * +140 * @param phase the phase to get the configured analyzers. +141 * @return the analyzers loaded +142 */ +143 public List<Analyzer> getAnalyzers(AnalysisPhase phase) { +144 return analyzers.get(phase); +145 } +146 +147 /** +148 * Get the dependencies identified. +149 * +150 * @return the dependencies identified +151 */ +152 public List<Dependency> getDependencies() { +153 return dependencies; +154 } +155 +156 /** +157 * Sets the dependencies. +158 * +159 * @param dependencies the dependencies +160 */ +161 public void setDependencies(List<Dependency> dependencies) { +162 this.dependencies = dependencies; +163 } +164 +165 /** +166 * Scans an array of files or directories. If a directory is specified, it will be scanned recursively. Any dependencies +167 * identified are added to the dependency collection. +168 * +169 * @param paths an array of paths to files or directories to be analyzed +170 * @return the list of dependencies scanned 171 * @since v0.3.2.5 172 */ 173 public List<Dependency> scan(String[] paths) { @@ -208,353 +208,325 @@ 200 * 201 * @param files an array of paths to files or directories to be analyzed. 202 * @return the list of dependencies -203 * -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 list 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 * -224 * @since v0.3.2.5 -225 */ -226 public List<Dependency> scan(Set<File> files) { -227 final List<Dependency> deps = new ArrayList<Dependency>(); -228 for (File file : files) { -229 final List<Dependency> d = scan(file); -230 if (d != null) { -231 deps.addAll(d); -232 } -233 } -234 return deps; -235 } -236 -237 /** -238 * Scans a list of files or directories. If a directory is specified, it will be scanned recursively. Any dependencies -239 * identified are added to the dependency collection. -240 * -241 * @param files a set of paths to files or directories to be analyzed -242 * @return the list of dependencies scanned -243 * -244 * @since v0.3.2.5 -245 */ -246 public List<Dependency> scan(List<File> files) { -247 final List<Dependency> deps = new ArrayList<Dependency>(); -248 for (File file : files) { -249 final List<Dependency> d = scan(file); -250 if (d != null) { -251 deps.addAll(d); -252 } -253 } -254 return deps; -255 } -256 -257 /** -258 * Scans a given file or directory. If a directory is specified, it will be scanned recursively. Any dependencies identified -259 * are added to the dependency collection. -260 * -261 * @param file the path to a file or directory to be analyzed -262 * @return the list of dependencies scanned -263 * -264 * @since v0.3.2.4 -265 * -266 */ -267 public List<Dependency> scan(File file) { -268 if (file.exists()) { -269 if (file.isDirectory()) { -270 return scanDirectory(file); -271 } else { -272 final Dependency d = scanFile(file); -273 if (d != null) { -274 final List<Dependency> deps = new ArrayList<Dependency>(); -275 deps.add(d); -276 return deps; -277 } -278 } -279 } -280 return null; -281 } -282 -283 /** -284 * Recursively scans files and directories. Any dependencies identified are added to the dependency collection. -285 * -286 * @param dir the directory to scan -287 * @return the list of Dependency objects scanned -288 */ -289 protected List<Dependency> scanDirectory(File dir) { -290 final File[] files = dir.listFiles(); -291 final List<Dependency> deps = new ArrayList<Dependency>(); -292 if (files != null) { -293 for (File f : files) { -294 if (f.isDirectory()) { -295 final List<Dependency> d = scanDirectory(f); -296 if (d != null) { -297 deps.addAll(d); -298 } -299 } else { -300 final Dependency d = scanFile(f); -301 deps.add(d); -302 } -303 } -304 } -305 return deps; -306 } -307 -308 /** -309 * Scans a specified file. If a dependency is identified it is added to the dependency collection. -310 * -311 * @param file The file to scan -312 * @return the scanned dependency -313 */ -314 protected Dependency scanFile(File file) { -315 if (!file.isFile()) { -316 final String msg = String.format("Path passed to scanFile(File) is not a file: %s. Skipping the file.", file.toString()); -317 LOGGER.log(Level.FINE, msg); -318 return null; -319 } -320 final String fileName = file.getName(); -321 String extension = FileUtils.getFileExtension(fileName); -322 if (null == extension) { -323 extension = fileName; -324 } -325 Dependency dependency = null; -326 if (supportsExtension(extension)) { -327 dependency = new Dependency(file); -328 if (extension == null ? fileName == null : extension.equals(fileName)) { -329 dependency.setFileExtension(extension); -330 } -331 dependencies.add(dependency); -332 } -333 return dependency; -334 } -335 -336 /** -337 * Runs the analyzers against all of the dependencies. -338 */ -339 public void analyzeDependencies() { -340 boolean autoUpdate = true; -341 try { -342 autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE); -343 } catch (InvalidSettingException ex) { -344 LOGGER.log(Level.FINE, "Invalid setting for auto-update; using true."); -345 } -346 if (autoUpdate) { -347 doUpdates(); -348 } -349 -350 //need to ensure that data exists -351 try { -352 ensureDataExists(); -353 } catch (NoDataException ex) { -354 final String msg = String.format("%s%n%nUnable to continue dependency-check analysis.", ex.getMessage()); -355 LOGGER.log(Level.SEVERE, msg); -356 LOGGER.log(Level.FINE, null, ex); -357 return; -358 } catch (DatabaseException ex) { -359 final String msg = String.format("%s%n%nUnable to continue dependency-check analysis.", ex.getMessage()); -360 LOGGER.log(Level.SEVERE, msg); -361 LOGGER.log(Level.FINE, null, ex); -362 return; -363 -364 } -365 -366 final String logHeader = String.format("%n" -367 + "----------------------------------------------------%n" -368 + "BEGIN ANALYSIS%n" -369 + "----------------------------------------------------"); -370 LOGGER.log(Level.FINE, logHeader); -371 LOGGER.log(Level.INFO, "Analysis Starting"); -372 -373 // analysis phases -374 for (AnalysisPhase phase : AnalysisPhase.values()) { -375 final List<Analyzer> analyzerList = analyzers.get(phase); -376 -377 for (Analyzer a : analyzerList) { -378 a = initializeAnalyzer(a); -379 -380 /* need to create a copy of the collection because some of the -381 * analyzers may modify it. This prevents ConcurrentModificationExceptions. -382 * This is okay for adds/deletes because it happens per analyzer. -383 */ -384 final String msg = String.format("Begin Analyzer '%s'", a.getName()); -385 LOGGER.log(Level.FINE, msg); -386 final Set<Dependency> dependencySet = new HashSet<Dependency>(); -387 dependencySet.addAll(dependencies); -388 for (Dependency d : dependencySet) { -389 boolean shouldAnalyze = true; -390 if (a instanceof FileTypeAnalyzer) { -391 final FileTypeAnalyzer fAnalyzer = (FileTypeAnalyzer) a; -392 shouldAnalyze = fAnalyzer.supportsExtension(d.getFileExtension()); -393 } -394 if (shouldAnalyze) { -395 final String msgFile = String.format("Begin Analysis of '%s'", d.getActualFilePath()); -396 LOGGER.log(Level.FINE, msgFile); -397 try { -398 a.analyze(d, this); -399 } catch (AnalysisException ex) { -400 final String exMsg = String.format("An error occurred while analyzing '%s'.", d.getActualFilePath()); -401 LOGGER.log(Level.WARNING, exMsg); -402 LOGGER.log(Level.FINE, "", ex); -403 } catch (Throwable ex) { -404 final String axMsg = String.format("An unexpected error occurred during analysis of '%s'", d.getActualFilePath()); -405 //final AnalysisException ax = new AnalysisException(axMsg, ex); -406 LOGGER.log(Level.WARNING, axMsg); -407 LOGGER.log(Level.FINE, "", ex); -408 } -409 } -410 } -411 } -412 } -413 for (AnalysisPhase phase : AnalysisPhase.values()) { -414 final List<Analyzer> analyzerList = analyzers.get(phase); -415 -416 for (Analyzer a : analyzerList) { -417 closeAnalyzer(a); -418 } -419 } -420 -421 final String logFooter = String.format("%n" -422 + "----------------------------------------------------%n" -423 + "END ANALYSIS%n" -424 + "----------------------------------------------------"); -425 LOGGER.log(Level.FINE, logFooter); -426 LOGGER.log(Level.INFO, "Analysis Complete"); -427 } -428 -429 /** -430 * Initializes the given analyzer. -431 * -432 * @param analyzer the analyzer to initialize -433 * @return the initialized analyzer -434 */ -435 protected Analyzer initializeAnalyzer(Analyzer analyzer) { -436 try { -437 final String msg = String.format("Initializing %s", analyzer.getName()); -438 LOGGER.log(Level.FINE, msg); -439 analyzer.initialize(); -440 } catch (Throwable ex) { -441 final String msg = String.format("Exception occurred initializing %s.", analyzer.getName()); -442 LOGGER.log(Level.SEVERE, msg); -443 LOGGER.log(Level.FINE, null, ex); -444 try { -445 analyzer.close(); -446 } catch (Throwable ex1) { -447 LOGGER.log(Level.FINEST, null, ex1); -448 } -449 } -450 return analyzer; -451 } -452 -453 /** -454 * Closes the given analyzer. -455 * -456 * @param analyzer the analyzer to close -457 */ -458 protected void closeAnalyzer(Analyzer analyzer) { -459 final String msg = String.format("Closing Analyzer '%s'", analyzer.getName()); -460 LOGGER.log(Level.FINE, msg); -461 try { -462 analyzer.close(); -463 } catch (Throwable ex) { -464 LOGGER.log(Level.FINEST, null, ex); -465 } -466 } -467 -468 /** -469 * Cycles through the cached web data sources and calls update on all of them. -470 */ -471 public void doUpdates() { -472 LOGGER.info("Checking for updates"); -473 final UpdateService service = new UpdateService(serviceClassLoader); -474 final Iterator<CachedWebDataSource> iterator = service.getDataSources(); -475 while (iterator.hasNext()) { -476 final CachedWebDataSource source = iterator.next(); -477 try { -478 source.update(); -479 } catch (UpdateException ex) { -480 LOGGER.log(Level.WARNING, -481 "Unable to update Cached Web DataSource, using local data instead. Results may not include recent vulnerabilities."); -482 LOGGER.log(Level.FINE, String.format("Unable to update details for %s", source.getClass().getName()), ex); -483 } -484 } -485 LOGGER.info("Check for updates complete"); -486 } -487 -488 /** -489 * Returns a full list of all of the analyzers. This is useful for reporting which analyzers where used. -490 * -491 * @return a list of Analyzers -492 */ -493 public List<Analyzer> getAnalyzers() { -494 final List<Analyzer> ret = new ArrayList<Analyzer>(); -495 for (AnalysisPhase phase : AnalysisPhase.values()) { -496 final List<Analyzer> analyzerList = analyzers.get(phase); -497 ret.addAll(analyzerList); -498 } -499 return ret; +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 list 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(Set<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 list of files or directories. If a directory is specified, it will be scanned recursively. Any dependencies +237 * identified are added to the dependency collection. +238 * +239 * @param files a set of paths to files or directories to be analyzed +240 * @return the list of dependencies scanned +241 * @since v0.3.2.5 +242 */ +243 public List<Dependency> scan(List<File> files) { +244 final List<Dependency> deps = new ArrayList<Dependency>(); +245 for (File file : files) { +246 final List<Dependency> d = scan(file); +247 if (d != null) { +248 deps.addAll(d); +249 } +250 } +251 return deps; +252 } +253 +254 /** +255 * Scans a given file or directory. If a directory is specified, it will be scanned recursively. Any dependencies identified +256 * are added to the dependency collection. +257 * +258 * @param file the path to a file or directory to be analyzed +259 * @return the list of dependencies scanned +260 * @since v0.3.2.4 +261 */ +262 public List<Dependency> scan(File file) { +263 if (file.exists()) { +264 if (file.isDirectory()) { +265 return scanDirectory(file); +266 } else { +267 final Dependency d = scanFile(file); +268 if (d != null) { +269 final List<Dependency> deps = new ArrayList<Dependency>(); +270 deps.add(d); +271 return deps; +272 } +273 } +274 } +275 return null; +276 } +277 +278 /** +279 * Recursively scans files and directories. Any dependencies identified are added to the dependency collection. +280 * +281 * @param dir the directory to scan +282 * @return the list of Dependency objects scanned +283 */ +284 protected List<Dependency> scanDirectory(File dir) { +285 final File[] files = dir.listFiles(); +286 final List<Dependency> deps = new ArrayList<Dependency>(); +287 if (files != null) { +288 for (File f : files) { +289 if (f.isDirectory()) { +290 final List<Dependency> d = scanDirectory(f); +291 if (d != null) { +292 deps.addAll(d); +293 } +294 } else { +295 final Dependency d = scanFile(f); +296 deps.add(d); +297 } +298 } +299 } +300 return deps; +301 } +302 +303 /** +304 * Scans a specified file. If a dependency is identified it is added to the dependency collection. +305 * +306 * @param file The file to scan +307 * @return the scanned dependency +308 */ +309 protected Dependency scanFile(File file) { +310 Dependency dependency = null; +311 if (file.isFile()) { +312 if (accept(file)) { +313 dependency = new Dependency(file); +314 dependencies.add(dependency); +315 } +316 } else { +317 LOGGER.debug("Path passed to scanFile(File) is not a file: {}. Skipping the file.", file); +318 } +319 return dependency; +320 } +321 +322 /** +323 * Runs the analyzers against all of the dependencies. Since the mutable dependencies list is exposed via +324 * {@link #getDependencies()}, this method iterates over a copy of the dependencies list. Thus, the potential for +325 * {@link java.util.ConcurrentModificationException}s is avoided, and analyzers may safely add or remove entries from the +326 * dependencies list. +327 */ +328 public void analyzeDependencies() { +329 boolean autoUpdate = true; +330 try { +331 autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE); +332 } catch (InvalidSettingException ex) { +333 LOGGER.debug("Invalid setting for auto-update; using true."); +334 } +335 if (autoUpdate) { +336 doUpdates(); +337 } +338 +339 //need to ensure that data exists +340 try { +341 ensureDataExists(); +342 } catch (NoDataException ex) { +343 LOGGER.error("{}\n\nUnable to continue dependency-check analysis.", ex.getMessage()); +344 LOGGER.debug("", ex); +345 return; +346 } catch (DatabaseException ex) { +347 LOGGER.error("{}\n\nUnable to continue dependency-check analysis.", ex.getMessage()); +348 LOGGER.debug("", ex); +349 return; +350 +351 } +352 +353 LOGGER.debug("\n----------------------------------------------------\nBEGIN ANALYSIS\n----------------------------------------------------"); +354 LOGGER.info("Analysis Starting"); +355 +356 // analysis phases +357 for (AnalysisPhase phase : AnalysisPhase.values()) { +358 final List<Analyzer> analyzerList = analyzers.get(phase); +359 +360 for (Analyzer a : analyzerList) { +361 a = initializeAnalyzer(a); +362 +363 /* need to create a copy of the collection because some of the +364 * analyzers may modify it. This prevents ConcurrentModificationExceptions. +365 * This is okay for adds/deletes because it happens per analyzer. +366 */ +367 LOGGER.debug("Begin Analyzer '{}'", a.getName()); +368 final Set<Dependency> dependencySet = new HashSet<Dependency>(); +369 dependencySet.addAll(dependencies); +370 for (Dependency d : dependencySet) { +371 boolean shouldAnalyze = true; +372 if (a instanceof FileTypeAnalyzer) { +373 final FileTypeAnalyzer fAnalyzer = (FileTypeAnalyzer) a; +374 shouldAnalyze = fAnalyzer.accept(d.getActualFile()); +375 } +376 if (shouldAnalyze) { +377 LOGGER.debug("Begin Analysis of '{}'", d.getActualFilePath()); +378 try { +379 a.analyze(d, this); +380 } catch (AnalysisException ex) { +381 LOGGER.warn("An error occurred while analyzing '{}'.", d.getActualFilePath()); +382 LOGGER.debug("", ex); +383 } catch (Throwable ex) { +384 //final AnalysisException ax = new AnalysisException(axMsg, ex); +385 LOGGER.warn("An unexpected error occurred during analysis of '{}'", d.getActualFilePath()); +386 LOGGER.debug("", ex); +387 } +388 } +389 } +390 } +391 } +392 for (AnalysisPhase phase : AnalysisPhase.values()) { +393 final List<Analyzer> analyzerList = analyzers.get(phase); +394 +395 for (Analyzer a : analyzerList) { +396 closeAnalyzer(a); +397 } +398 } +399 +400 LOGGER.debug("\n----------------------------------------------------\nEND ANALYSIS\n----------------------------------------------------"); +401 LOGGER.info("Analysis Complete"); +402 } +403 +404 /** +405 * Initializes the given analyzer. +406 * +407 * @param analyzer the analyzer to initialize +408 * @return the initialized analyzer +409 */ +410 protected Analyzer initializeAnalyzer(Analyzer analyzer) { +411 try { +412 LOGGER.debug("Initializing {}", analyzer.getName()); +413 analyzer.initialize(); +414 } catch (Throwable ex) { +415 LOGGER.error("Exception occurred initializing {}.", analyzer.getName()); +416 LOGGER.debug("", ex); +417 try { +418 analyzer.close(); +419 } catch (Throwable ex1) { +420 LOGGER.trace("", ex1); +421 } +422 } +423 return analyzer; +424 } +425 +426 /** +427 * Closes the given analyzer. +428 * +429 * @param analyzer the analyzer to close +430 */ +431 protected void closeAnalyzer(Analyzer analyzer) { +432 LOGGER.debug("Closing Analyzer '{}'", analyzer.getName()); +433 try { +434 analyzer.close(); +435 } catch (Throwable ex) { +436 LOGGER.trace("", ex); +437 } +438 } +439 +440 /** +441 * Cycles through the cached web data sources and calls update on all of them. +442 */ +443 public void doUpdates() { +444 LOGGER.info("Checking for updates"); +445 final UpdateService service = new UpdateService(serviceClassLoader); +446 final Iterator<CachedWebDataSource> iterator = service.getDataSources(); +447 while (iterator.hasNext()) { +448 final CachedWebDataSource source = iterator.next(); +449 try { +450 source.update(); +451 } catch (UpdateException ex) { +452 LOGGER.warn( +453 "Unable to update Cached Web DataSource, using local data instead. Results may not include recent vulnerabilities."); +454 LOGGER.debug("Unable to update details for {}", source.getClass().getName(), ex); +455 } +456 } +457 LOGGER.info("Check for updates complete"); +458 } +459 +460 /** +461 * Returns a full list of all of the analyzers. This is useful for reporting which analyzers where used. +462 * +463 * @return a list of Analyzers +464 */ +465 public List<Analyzer> getAnalyzers() { +466 final List<Analyzer> ret = new ArrayList<Analyzer>(); +467 for (AnalysisPhase phase : AnalysisPhase.values()) { +468 final List<Analyzer> analyzerList = analyzers.get(phase); +469 ret.addAll(analyzerList); +470 } +471 return ret; +472 } +473 +474 /** +475 * Checks all analyzers to see if an extension is supported. +476 * +477 * @param file a file extension +478 * @return true or false depending on whether or not the file extension is supported +479 */ +480 public boolean accept(File file) { +481 if (file == null) { +482 return false; +483 } +484 boolean scan = false; +485 for (FileTypeAnalyzer a : this.fileTypeAnalyzers) { +486 /* note, we can't break early on this loop as the analyzers need to know if +487 they have files to work on prior to initialization */ +488 scan |= a.accept(file); +489 } +490 return scan; +491 } +492 +493 /** +494 * Returns the set of file type analyzers. +495 * +496 * @return the set of file type analyzers +497 */ +498 public Set<FileTypeAnalyzer> getFileTypeAnalyzers() { +499 return this.fileTypeAnalyzers; 500 } 501 502 /** -503 * Checks all analyzers to see if an extension is supported. +503 * Checks the CPE Index to ensure documents exists. If none exist a NoDataException is thrown. 504 * -505 * @param ext a file extension -506 * @return true or false depending on whether or not the file extension is supported +505 * @throws NoDataException thrown if no data exists in the CPE Index +506 * @throws DatabaseException thrown if there is an exception opening the database 507 */ -508 public boolean supportsExtension(String ext) { -509 if (ext == null) { -510 return false; -511 } -512 boolean scan = false; -513 for (FileTypeAnalyzer a : this.fileTypeAnalyzers) { -514 /* note, we can't break early on this loop as the analyzers need to know if -515 they have files to work on prior to initialization */ -516 scan |= a.supportsExtension(ext); -517 } -518 return scan; -519 } -520 -521 /** -522 * Returns the set of file type analyzers. -523 * -524 * @return the set of file type analyzers -525 */ -526 public Set<FileTypeAnalyzer> getFileTypeAnalyzers() { -527 return this.fileTypeAnalyzers; -528 } -529 -530 /** -531 * Checks the CPE Index to ensure documents exists. If none exist a NoDataException is thrown. -532 * -533 * @throws NoDataException thrown if no data exists in the CPE Index -534 * @throws DatabaseException thrown if there is an exception opening the database -535 */ -536 private void ensureDataExists() throws NoDataException, DatabaseException { -537 final CveDB cve = new CveDB(); -538 try { -539 cve.open(); -540 if (!cve.dataExists()) { -541 throw new NoDataException("No documents exist"); -542 } -543 } catch (DatabaseException ex) { -544 throw new NoDataException(ex.getMessage(), ex); -545 } finally { -546 cve.close(); -547 } -548 } -549 } +508 private void ensureDataExists() throws NoDataException, DatabaseException { +509 final CveDB cve = new CveDB(); +510 try { +511 cve.open(); +512 if (!cve.dataExists()) { +513 throw new NoDataException("No documents exist"); +514 } +515 } catch (DatabaseException ex) { +516 throw new NoDataException(ex.getMessage(), ex); +517 } finally { +518 cve.close(); +519 } +520 } +521 }
    diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/agent/DependencyCheckScanAgent.html b/dependency-check-core/xref/org/owasp/dependencycheck/agent/DependencyCheckScanAgent.html index fd12f6af2..940b0f3e2 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/agent/DependencyCheckScanAgent.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/agent/DependencyCheckScanAgent.html @@ -28,18 +28,18 @@ 20 import java.io.File; 21 import java.io.IOException; 22 import java.util.List; -23 import java.util.logging.Level; -24 import java.util.logging.Logger; -25 import org.owasp.dependencycheck.Engine; -26 import org.owasp.dependencycheck.data.nvdcve.CveDB; -27 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; -28 import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties; -29 import org.owasp.dependencycheck.dependency.Dependency; -30 import org.owasp.dependencycheck.dependency.Identifier; -31 import org.owasp.dependencycheck.dependency.Vulnerability; -32 import org.owasp.dependencycheck.exception.ScanAgentException; -33 import org.owasp.dependencycheck.reporting.ReportGenerator; -34 import org.owasp.dependencycheck.utils.Settings; +23 import org.owasp.dependencycheck.Engine; +24 import org.owasp.dependencycheck.data.nvdcve.CveDB; +25 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; +26 import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties; +27 import org.owasp.dependencycheck.dependency.Dependency; +28 import org.owasp.dependencycheck.dependency.Identifier; +29 import org.owasp.dependencycheck.dependency.Vulnerability; +30 import org.owasp.dependencycheck.exception.ScanAgentException; +31 import org.owasp.dependencycheck.reporting.ReportGenerator; +32 import org.owasp.dependencycheck.utils.Settings; +33 import org.slf4j.Logger; +34 import org.slf4j.LoggerFactory; 35 36 /** 37 * This class provides a way to easily conduct a scan solely based on existing evidence metadata rather than collecting evidence @@ -75,7 +75,7 @@ 67 /** 68 * Logger for use throughout the class. 69 */ -70 private static final Logger LOGGER = Logger.getLogger(DependencyCheckScanAgent.class.getName()); +70 private static final Logger LOGGER = LoggerFactory.getLogger(DependencyCheckScanAgent.class); 71 /** 72 * The application name for the report. 73 */ @@ -869,7 +869,7 @@ 861 cve.open(); 862 prop = cve.getDatabaseProperties(); 863 } catch (DatabaseException ex) { -864 LOGGER.log(Level.FINE, "Unable to retrieve DB Properties", ex); +864 LOGGER.debug("Unable to retrieve DB Properties", ex); 865 } finally { 866 if (cve != null) { 867 cve.close(); @@ -879,13 +879,13 @@ 871 try { 872 r.generateReports(outDirectory.getCanonicalPath(), this.reportFormat.name()); 873 } catch (IOException ex) { -874 LOGGER.log(Level.SEVERE, +874 LOGGER.error( 875 "Unexpected exception occurred during analysis; please see the verbose error log for more details."); -876 LOGGER.log(Level.FINE, null, ex); +876 LOGGER.debug("", ex); 877 } catch (Throwable ex) { -878 LOGGER.log(Level.SEVERE, +878 LOGGER.error( 879 "Unexpected exception occurred during analysis; please see the verbose error log for more details."); -880 LOGGER.log(Level.FINE, null, ex); +880 LOGGER.debug("", ex); 881 } 882 } 883 @@ -989,9 +989,9 @@ 981 checkForFailure(engine.getDependencies()); 982 } 983 } catch (DatabaseException ex) { -984 LOGGER.log(Level.SEVERE, +984 LOGGER.error( 985 "Unable to connect to the dependency-check database; analysis has stopped"); -986 LOGGER.log(Level.FINE, "", ex); +986 LOGGER.debug("", ex); 987 } finally { 988 Settings.cleanup(true); 989 if (engine != null) { @@ -1066,14 +1066,13 @@ 1058 } 1059 } 1060 if (summary.length() > 0) { -1061 final String msg = String.format("%n%n" -1062 + "One or more dependencies were identified with known vulnerabilities:%n%n%s" -1063 + "%n%nSee the dependency-check report for more details.%n%n", summary.toString()); -1064 LOGGER.log(Level.WARNING, msg); -1065 } -1066 } -1067 -1068 } +1061 LOGGER.warn("\n\nOne or more dependencies were identified with known vulnerabilities:\n\n{}\n\n" +1062 + "See the dependency-check report for more details.\n\n", +1063 summary.toString()); +1064 } +1065 } +1066 +1067 }
    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 bdcbe0d4a..b489abcc2 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.2.11 Reference Package org.owasp.dependencycheck.agent + Dependency-Check Core 1.3.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 57dedf4bb..5b159260e 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.2.11 Reference Package org.owasp.dependencycheck.agent + Dependency-Check Core 1.3.0 Reference Package org.owasp.dependencycheck.agent diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AbstractFileTypeAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AbstractFileTypeAnalyzer.html index 3510accc7..9630ee9ef 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AbstractFileTypeAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AbstractFileTypeAnalyzer.html @@ -25,224 +25,210 @@ 17 */ 18 package org.owasp.dependencycheck.analyzer; 19 -20 import java.util.Collections; -21 import java.util.HashSet; -22 import java.util.Set; -23 import java.util.logging.Level; -24 import java.util.logging.Logger; -25 import org.owasp.dependencycheck.Engine; -26 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; -27 import org.owasp.dependencycheck.dependency.Dependency; -28 import org.owasp.dependencycheck.utils.InvalidSettingException; -29 import org.owasp.dependencycheck.utils.Settings; -30 -31 /** -32 * The base FileTypeAnalyzer that all analyzers that have specific file types they analyze should extend. -33 * -34 * @author Jeremy Long -35 */ -36 public abstract class AbstractFileTypeAnalyzer extends AbstractAnalyzer implements FileTypeAnalyzer { -37 -38 //<editor-fold defaultstate="collapsed" desc="Constructor"> -39 /** -40 * Base constructor that all children must call. This checks the configuration to determine if the analyzer is -41 * enabled. -42 */ -43 public AbstractFileTypeAnalyzer() { -44 reset(); -45 } -46 //</editor-fold> -47 -48 //<editor-fold defaultstate="collapsed" desc="Field definitions"> -49 /** -50 * The logger. -51 */ -52 private static final Logger LOGGER = Logger.getLogger(AbstractFileTypeAnalyzer.class.getName()); -53 /** -54 * Whether the file type analyzer detected any files it needs to analyze. -55 */ -56 private boolean filesMatched = false; -57 -58 /** -59 * Get the value of filesMatched. A flag indicating whether the scan included any file types this analyzer supports. -60 * -61 * @return the value of filesMatched -62 */ -63 protected boolean isFilesMatched() { -64 return filesMatched; -65 } -66 -67 /** -68 * Set the value of filesMatched. A flag indicating whether the scan included any file types this analyzer supports. -69 * -70 * @param filesMatched new value of filesMatched -71 */ -72 protected void setFilesMatched(boolean filesMatched) { -73 this.filesMatched = filesMatched; -74 } -75 -76 /** -77 * A flag indicating whether or not the analyzer is enabled. -78 */ -79 private boolean enabled = true; -80 -81 /** -82 * Get the value of enabled. -83 * -84 * @return the value of enabled -85 */ -86 public boolean isEnabled() { -87 return enabled; -88 } -89 -90 /** -91 * Set the value of enabled. -92 * -93 * @param enabled new value of enabled -94 */ -95 public void setEnabled(boolean enabled) { -96 this.enabled = enabled; -97 } -98 //</editor-fold> -99 -100 //<editor-fold defaultstate="collapsed" desc="Abstract methods children must implement"> -101 /** -102 * <p> -103 * Returns a list of supported file extensions. An example would be an analyzer that inspected java jar files. The -104 * getSupportedExtensions function would return a set with a single element "jar".</p> -105 * -106 * <p> -107 * <b>Note:</b> when implementing this the extensions returned MUST be lowercase.</p> -108 * -109 * @return The file extensions supported by this analyzer. -110 * -111 * <p> -112 * If the analyzer returns null it will not cause additional files to be analyzed but will be executed against every -113 * file loaded</p> -114 */ -115 protected abstract Set<String> getSupportedExtensions(); -116 -117 /** -118 * Initializes the file type analyzer. -119 * -120 * @throws Exception thrown if there is an exception during initialization -121 */ -122 protected abstract void initializeFileTypeAnalyzer() throws Exception; -123 -124 /** -125 * Analyzes a given dependency. If the dependency is an archive, such as a WAR or EAR, the contents are extracted, -126 * scanned, and added to the list of dependencies within the engine. -127 * -128 * @param dependency the dependency to analyze -129 * @param engine the engine scanning -130 * @throws AnalysisException thrown if there is an analysis exception -131 */ -132 protected abstract void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException; -133 -134 /** -135 * <p> -136 * Returns the setting key to determine if the analyzer is enabled.</p> -137 * -138 * @return the key for the analyzer's enabled property -139 */ -140 protected abstract String getAnalyzerEnabledSettingKey(); -141 -142 //</editor-fold> -143 //<editor-fold defaultstate="collapsed" desc="Final implementations for the Analyzer interface"> -144 /** -145 * Initializes the analyzer. -146 * -147 * @throws Exception thrown if there is an exception during initialization -148 */ -149 @Override -150 public final void initialize() throws Exception { -151 if (filesMatched) { -152 initializeFileTypeAnalyzer(); -153 } else { -154 enabled = false; -155 } -156 } -157 -158 /** -159 * Resets the enabled flag on the analyzer. -160 */ -161 @Override -162 public final void reset() { -163 final String key = getAnalyzerEnabledSettingKey(); -164 try { -165 enabled = Settings.getBoolean(key, true); -166 } catch (InvalidSettingException ex) { -167 String msg = String.format("Invalid setting for property '%s'", key); -168 LOGGER.log(Level.WARNING, msg); -169 LOGGER.log(Level.FINE, "", ex); -170 msg = String.format("%s has been disabled", getName()); -171 LOGGER.log(Level.WARNING, msg); -172 } -173 } -174 -175 /** -176 * Analyzes a given dependency. If the dependency is an archive, such as a WAR or EAR, the contents are extracted, -177 * scanned, and added to the list of dependencies within the engine. -178 * -179 * @param dependency the dependency to analyze -180 * @param engine the engine scanning -181 * @throws AnalysisException thrown if there is an analysis exception -182 */ -183 @Override -184 public final void analyze(Dependency dependency, Engine engine) throws AnalysisException { -185 if (enabled) { -186 analyzeFileType(dependency, engine); -187 } -188 } -189 -190 /** -191 * Returns whether or not this analyzer can process the given extension. -192 * -193 * @param extension the file extension to test for support. -194 * @return whether or not the specified file extension is supported by this analyzer. -195 */ -196 @Override -197 public final boolean supportsExtension(String extension) { -198 if (!enabled) { -199 return false; -200 } -201 final Set<String> ext = getSupportedExtensions(); -202 if (ext == null) { -203 final String msg = String.format("The '%s' analyzer is misconfigured and does not have any file extensions;" -204 + " it will be disabled", getName()); -205 LOGGER.log(Level.SEVERE, msg); -206 return false; -207 } else { -208 final boolean match = ext.contains(extension); -209 if (match) { -210 filesMatched = match; -211 } -212 return match; -213 } -214 } -215 //</editor-fold> -216 -217 //<editor-fold defaultstate="collapsed" desc="Static utility methods"> -218 /** -219 * <p> -220 * Utility method to help in the creation of the extensions set. This constructs a new Set that can be used in a -221 * final static declaration.</p> -222 * -223 * <p> -224 * This implementation was copied from -225 * http://stackoverflow.com/questions/2041778/initialize-java-hashset-values-by-construction</p>; -226 * -227 * @param strings a list of strings to add to the set. -228 * @return a Set of strings. -229 */ -230 protected static Set<String> newHashSet(String... strings) { -231 final Set<String> set = new HashSet<String>(); -232 -233 Collections.addAll(set, strings); -234 return set; -235 } -236 //</editor-fold> -237 } +20 import org.owasp.dependencycheck.Engine; +21 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; +22 import org.owasp.dependencycheck.dependency.Dependency; +23 import org.owasp.dependencycheck.utils.InvalidSettingException; +24 import org.owasp.dependencycheck.utils.Settings; +25 import org.slf4j.Logger; +26 import org.slf4j.LoggerFactory; +27 +28 import java.io.File; +29 import java.io.FileFilter; +30 import java.util.Collections; +31 import java.util.HashSet; +32 import java.util.Set; +33 +34 /** +35 * The base FileTypeAnalyzer that all analyzers that have specific file types they analyze should extend. +36 * +37 * @author Jeremy Long +38 */ +39 public abstract class AbstractFileTypeAnalyzer extends AbstractAnalyzer implements FileTypeAnalyzer { +40 +41 //<editor-fold defaultstate="collapsed" desc="Constructor"> +42 /** +43 * Base constructor that all children must call. This checks the configuration to determine if the analyzer is enabled. +44 */ +45 public AbstractFileTypeAnalyzer() { +46 reset(); +47 } +48 //</editor-fold> +49 +50 //<editor-fold defaultstate="collapsed" desc="Field definitions"> +51 /** +52 * The logger. +53 */ +54 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 private boolean filesMatched = false; +59 +60 /** +61 * Get the value of filesMatched. A flag indicating whether the scan included any file types this analyzer supports. +62 * +63 * @return the value of filesMatched +64 */ +65 protected boolean isFilesMatched() { +66 return filesMatched; +67 } +68 +69 /** +70 * Set the value of filesMatched. A flag indicating whether the scan included any file types this analyzer supports. +71 * +72 * @param filesMatched new value of filesMatched +73 */ +74 protected void setFilesMatched(boolean filesMatched) { +75 this.filesMatched = filesMatched; +76 } +77 +78 /** +79 * A flag indicating whether or not the analyzer is enabled. +80 */ +81 private boolean enabled = true; +82 +83 /** +84 * Get the value of enabled. +85 * +86 * @return the value of enabled +87 */ +88 public boolean isEnabled() { +89 return enabled; +90 } +91 +92 /** +93 * Set the value of enabled. +94 * +95 * @param enabled new value of enabled +96 */ +97 public void setEnabled(boolean enabled) { +98 this.enabled = enabled; +99 } +100 //</editor-fold> +101 +102 //<editor-fold defaultstate="collapsed" desc="Abstract methods children must implement"> +103 /** +104 * <p> +105 * Returns the {@link java.io.FileFilter} used to determine which files are to be analyzed. An example would be an analyzer +106 * that inspected Java jar files. Implementors may use {@link org.owasp.dependencycheck.utils.FileFilterBuilder}.</p> +107 * +108 * @return the file filter used to determine which files are to be analyzed +109 * <p/> +110 * <p> +111 * If the analyzer returns null it will not cause additional files to be analyzed, but will be executed against every file +112 * loaded.</p> +113 */ +114 protected abstract FileFilter getFileFilter(); +115 +116 /** +117 * Initializes the file type analyzer. +118 * +119 * @throws Exception thrown if there is an exception during initialization +120 */ +121 protected abstract void initializeFileTypeAnalyzer() throws Exception; +122 +123 /** +124 * Analyzes a given dependency. If the dependency is an archive, such as a WAR or EAR, the contents are extracted, scanned, +125 * and added to the list of dependencies within the engine. +126 * +127 * @param dependency the dependency to analyze +128 * @param engine the engine scanning +129 * @throws AnalysisException thrown if there is an analysis exception +130 */ +131 protected abstract void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException; +132 +133 /** +134 * <p> +135 * Returns the setting key to determine if the analyzer is enabled.</p> +136 * +137 * @return the key for the analyzer's enabled property +138 */ +139 protected abstract String getAnalyzerEnabledSettingKey(); +140 +141 //</editor-fold> +142 //<editor-fold defaultstate="collapsed" desc="Final implementations for the Analyzer interface"> +143 /** +144 * Initializes the analyzer. +145 * +146 * @throws Exception thrown if there is an exception during initialization +147 */ +148 @Override +149 public final void initialize() throws Exception { +150 if (filesMatched) { +151 initializeFileTypeAnalyzer(); +152 } else { +153 enabled = false; +154 } +155 } +156 +157 /** +158 * Resets the enabled flag on the analyzer. +159 */ +160 @Override +161 public final void reset() { +162 final String key = getAnalyzerEnabledSettingKey(); +163 try { +164 enabled = Settings.getBoolean(key, true); +165 } catch (InvalidSettingException ex) { +166 LOGGER.warn("Invalid setting for property '{}'", key); +167 LOGGER.debug("", ex); +168 LOGGER.warn("{} has been disabled", getName()); +169 } +170 } +171 +172 /** +173 * Analyzes a given dependency. If the dependency is an archive, such as a WAR or EAR, the contents are extracted, scanned, +174 * and added to the list of dependencies within the engine. +175 * +176 * @param dependency the dependency to analyze +177 * @param engine the engine scanning +178 * @throws AnalysisException thrown if there is an analysis exception +179 */ +180 @Override +181 public final void analyze(Dependency dependency, Engine engine) throws AnalysisException { +182 if (enabled) { +183 analyzeFileType(dependency, engine); +184 } +185 } +186 +187 @Override +188 public boolean accept(File pathname) { +189 final FileFilter filter = getFileFilter(); +190 boolean accepted = false; +191 if (null == filter) { +192 LOGGER.error("The '{}' analyzer is misconfigured and does not have a file filter; it will be disabled", getName()); +193 } else if (enabled) { +194 accepted = filter.accept(pathname); +195 if (accepted) { +196 filesMatched = true; +197 } +198 } +199 return accepted; +200 } +201 +202 //</editor-fold> +203 //<editor-fold defaultstate="collapsed" desc="Static utility methods"> +204 /** +205 * <p> +206 * Utility method to help in the creation of the extensions set. This constructs a new Set that can be used in a final static +207 * declaration.</p> +208 * <p/> +209 * <p> +210 * This implementation was copied from +211 * http://stackoverflow.com/questions/2041778/initialize-java-hashset-values-by-construction</p>; +212 * +213 * @param strings a list of strings to add to the set. +214 * @return a Set of strings. +215 */ +216 protected static Set<String> newHashSet(String... strings) { +217 final Set<String> set = new HashSet<String>(); +218 Collections.addAll(set, strings); +219 return set; +220 } +221 +222 //</editor-fold> +223 }
    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 787cfef18..f2141d45f 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzer.html @@ -32,16 +32,16 @@ 24 import java.net.URL; 25 import java.util.List; 26 import java.util.Set; -27 import java.util.logging.Level; -28 import java.util.logging.Logger; -29 import java.util.regex.Pattern; -30 import org.owasp.dependencycheck.suppression.SuppressionParseException; -31 import org.owasp.dependencycheck.suppression.SuppressionParser; -32 import org.owasp.dependencycheck.suppression.SuppressionRule; -33 import org.owasp.dependencycheck.utils.DownloadFailedException; -34 import org.owasp.dependencycheck.utils.Downloader; -35 import org.owasp.dependencycheck.utils.FileUtils; -36 import org.owasp.dependencycheck.utils.Settings; +27 import java.util.regex.Pattern; +28 import org.owasp.dependencycheck.suppression.SuppressionParseException; +29 import org.owasp.dependencycheck.suppression.SuppressionParser; +30 import org.owasp.dependencycheck.suppression.SuppressionRule; +31 import org.owasp.dependencycheck.utils.DownloadFailedException; +32 import org.owasp.dependencycheck.utils.Downloader; +33 import org.owasp.dependencycheck.utils.FileUtils; +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. @@ -53,7 +53,7 @@ 45 /** 46 * The Logger for use throughout the class 47 */ -48 private static final Logger LOGGER = Logger.getLogger(AbstractSuppressionAnalyzer.class.getName()); +48 private static final Logger LOGGER = LoggerFactory.getLogger(AbstractSuppressionAnalyzer.class); 49 50 //<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer"> 51 /** @@ -111,7 +111,7 @@ 103 try { 104 rules = parser.parseSuppressionRules(this.getClass().getClassLoader().getResourceAsStream("dependencycheck-base-suppression.xml")); 105 } catch (SuppressionParseException ex) { -106 LOGGER.log(Level.FINE, "Unable to parse the base suppression data file", 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) { @@ -149,41 +149,40 @@ 141 try { 142 //rules = parser.parseSuppressionRules(file); 143 rules.addAll(parser.parseSuppressionRules(file)); -144 LOGGER.log(Level.FINE, rules.size() + " suppression rules were loaded."); +144 LOGGER.debug("{} suppression rules were loaded.", rules.size()); 145 } catch (SuppressionParseException ex) { -146 final String msg = String.format("Unable to parse suppression xml file '%s'", file.getPath()); -147 LOGGER.log(Level.WARNING, msg); -148 LOGGER.log(Level.WARNING, ex.getMessage()); -149 LOGGER.log(Level.FINE, "", ex); -150 throw ex; -151 } -152 } -153 } catch (DownloadFailedException ex) { -154 throwSuppressionParseException("Unable to fetch the configured suppression file", ex); -155 } catch (MalformedURLException ex) { -156 throwSuppressionParseException("Configured suppression file has an invalid URL", ex); -157 } catch (IOException ex) { -158 throwSuppressionParseException("Unable to create temp file for suppressions", ex); -159 } finally { -160 if (deleteTempFile && file != null) { -161 FileUtils.delete(file); -162 } -163 } -164 } -165 -166 /** -167 * Utility method to throw parse exceptions. -168 * -169 * @param message the exception message -170 * @param exception the cause of the exception -171 * @throws SuppressionParseException throws the generated SuppressionParseException -172 */ -173 private void throwSuppressionParseException(String message, Exception exception) throws SuppressionParseException { -174 LOGGER.log(Level.WARNING, message); -175 LOGGER.log(Level.FINE, "", exception); -176 throw new SuppressionParseException(message, exception); -177 } -178 } +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 }
    diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/ArchiveAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/ArchiveAnalyzer.html index 2cf2badcc..4a850967c 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/ArchiveAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/ArchiveAnalyzer.html @@ -28,19 +28,19 @@ 20 import java.io.BufferedInputStream; 21 import java.io.BufferedOutputStream; 22 import java.io.File; -23 import java.io.FileInputStream; -24 import java.io.FileNotFoundException; -25 import java.io.FileOutputStream; -26 import java.io.IOException; -27 import java.util.ArrayList; -28 import java.util.Arrays; -29 import java.util.Collections; -30 import java.util.Enumeration; -31 import java.util.HashSet; -32 import java.util.List; -33 import java.util.Set; -34 import java.util.logging.Level; -35 import java.util.logging.Logger; +23 import java.io.FileFilter; +24 import java.io.FileInputStream; +25 import java.io.FileNotFoundException; +26 import java.io.FileOutputStream; +27 import java.io.IOException; +28 import java.util.ArrayList; +29 import java.util.Arrays; +30 import java.util.Collections; +31 import java.util.Enumeration; +32 import java.util.HashSet; +33 import java.util.List; +34 import java.util.Set; +35 36 import org.apache.commons.compress.archivers.ArchiveEntry; 37 import org.apache.commons.compress.archivers.ArchiveInputStream; 38 import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; @@ -54,458 +54,460 @@ 46 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; 47 import org.owasp.dependencycheck.analyzer.exception.ArchiveExtractionException; 48 import org.owasp.dependencycheck.dependency.Dependency; -49 import org.owasp.dependencycheck.utils.FileUtils; -50 import org.owasp.dependencycheck.utils.Settings; -51 -52 /** -53 * <p> -54 * An analyzer that extracts files from archives and ensures any supported files contained within the archive are added -55 * to the dependency list.</p> -56 * -57 * @author Jeremy Long -58 */ -59 public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer { -60 -61 /** -62 * The logger. -63 */ -64 private static final Logger LOGGER = Logger.getLogger(ArchiveAnalyzer.class.getName()); -65 /** -66 * The buffer size to use when extracting files from the archive. -67 */ -68 private static final int BUFFER_SIZE = 4096; -69 /** -70 * The count of directories created during analysis. This is used for creating temporary directories. -71 */ -72 private static int dirCount = 0; -73 /** -74 * The parent directory for the individual directories per archive. -75 */ -76 private File tempFileLocation = null; -77 /** -78 * The max scan depth that the analyzer will recursively extract nested archives. -79 */ -80 private static final int MAX_SCAN_DEPTH = Settings.getInt("archive.scan.depth", 3); -81 /** -82 * Tracks the current scan/extraction depth for nested archives. -83 */ -84 private int scanDepth = 0; -85 -86 //<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer"> -87 /** -88 * The name of the analyzer. -89 */ -90 private static final String ANALYZER_NAME = "Archive Analyzer"; -91 /** -92 * The phase that this analyzer is intended to run in. -93 */ -94 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INITIAL; -95 /** -96 * The set of things we can handle with Zip methods -97 */ -98 private static final Set<String> ZIPPABLES = newHashSet("zip", "ear", "war", "jar", "sar", "apk", "nupkg"); -99 /** -100 * The set of file extensions supported by this analyzer. Note for developers, any additions to this list will need -101 * to be explicitly handled in extractFiles(). -102 */ -103 private static final Set<String> EXTENSIONS = newHashSet("tar", "gz", "tgz"); -104 -105 /** -106 * The set of file extensions to remove from the engine's collection of dependencies. -107 */ -108 private static final Set<String> REMOVE_FROM_ANALYSIS = newHashSet("zip", "tar", "gz", "tgz"); //TODO add nupkg, apk, sar? -109 -110 static { -111 final String additionalZipExt = Settings.getString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS); -112 if (additionalZipExt != null) { -113 final Set<String> ext = new HashSet<String>(Arrays.asList(additionalZipExt)); -114 ZIPPABLES.addAll(ext); -115 } -116 EXTENSIONS.addAll(ZIPPABLES); -117 } -118 -119 /** -120 * Returns a list of file EXTENSIONS supported by this analyzer. -121 * -122 * @return a list of file EXTENSIONS supported by this analyzer. -123 */ -124 @Override -125 public Set<String> getSupportedExtensions() { -126 return EXTENSIONS; -127 } -128 -129 /** -130 * Returns the name of the analyzer. -131 * -132 * @return the name of the analyzer. -133 */ -134 @Override -135 public String getName() { -136 return ANALYZER_NAME; -137 } -138 -139 /** -140 * Returns the phase that the analyzer is intended to run in. -141 * -142 * @return the phase that the analyzer is intended to run in. -143 */ -144 @Override -145 public AnalysisPhase getAnalysisPhase() { -146 return ANALYSIS_PHASE; -147 } -148 //</editor-fold> -149 -150 /** -151 * Returns the key used in the properties file to reference the analyzer's enabled property. -152 * -153 * @return the analyzer's enabled property setting key -154 */ -155 @Override -156 protected String getAnalyzerEnabledSettingKey() { -157 return Settings.KEYS.ANALYZER_ARCHIVE_ENABLED; -158 } -159 -160 /** -161 * The initialize method does nothing for this Analyzer. -162 * -163 * @throws Exception is thrown if there is an exception deleting or creating temporary files -164 */ -165 @Override -166 public void initializeFileTypeAnalyzer() throws Exception { -167 final File baseDir = Settings.getTempDirectory(); -168 tempFileLocation = File.createTempFile("check", "tmp", baseDir); -169 if (!tempFileLocation.delete()) { -170 final String msg = String.format("Unable to delete temporary file '%s'.", tempFileLocation.getAbsolutePath()); -171 throw new AnalysisException(msg); -172 } -173 if (!tempFileLocation.mkdirs()) { -174 final String msg = String.format("Unable to create directory '%s'.", tempFileLocation.getAbsolutePath()); -175 throw new AnalysisException(msg); -176 } -177 } -178 -179 /** -180 * The close method deletes any temporary files and directories created during analysis. -181 * -182 * @throws Exception thrown if there is an exception deleting temporary files -183 */ -184 @Override -185 public void close() throws Exception { -186 if (tempFileLocation != null && tempFileLocation.exists()) { -187 LOGGER.log(Level.FINE, "Attempting to delete temporary files"); -188 final boolean success = FileUtils.delete(tempFileLocation); -189 if (!success && tempFileLocation != null && tempFileLocation.exists() && tempFileLocation.list().length > 0) { -190 LOGGER.log(Level.WARNING, "Failed to delete some temporary files, see the log for more details"); -191 } -192 } -193 } -194 -195 /** -196 * Analyzes a given dependency. If the dependency is an archive, such as a WAR or EAR, the contents are extracted, -197 * scanned, and added to the list of dependencies within the engine. -198 * -199 * @param dependency the dependency to analyze -200 * @param engine the engine scanning -201 * @throws AnalysisException thrown if there is an analysis exception -202 */ -203 @Override -204 public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { -205 final File f = new File(dependency.getActualFilePath()); -206 final File tmpDir = getNextTempDirectory(); -207 extractFiles(f, tmpDir, engine); -208 -209 //make a copy -210 List<Dependency> dependencies = new ArrayList<Dependency>(engine.getDependencies()); -211 engine.scan(tmpDir); -212 List<Dependency> newDependencies = engine.getDependencies(); -213 if (dependencies.size() != newDependencies.size()) { -214 //get the new dependencies -215 final Set<Dependency> dependencySet = new HashSet<Dependency>(); -216 dependencySet.addAll(newDependencies); -217 dependencySet.removeAll(dependencies); -218 -219 for (Dependency d : dependencySet) { -220 //fix the dependency's display name and path -221 final String displayPath = String.format("%s%s", -222 dependency.getFilePath(), -223 d.getActualFilePath().substring(tmpDir.getAbsolutePath().length())); -224 final String displayName = String.format("%s: %s", -225 dependency.getFileName(), -226 d.getFileName()); -227 d.setFilePath(displayPath); -228 d.setFileName(displayName); -229 -230 //TODO - can we get more evidence from the parent? EAR contains module name, etc. -231 //analyze the dependency (i.e. extract files) if it is a supported type. -232 if (this.supportsExtension(d.getFileExtension()) && scanDepth < MAX_SCAN_DEPTH) { -233 scanDepth += 1; -234 analyze(d, engine); -235 scanDepth -= 1; -236 } -237 } -238 } -239 if (this.REMOVE_FROM_ANALYSIS.contains(dependency.getFileExtension())) { -240 if ("zip".equals(dependency.getFileExtension()) && isZipFileActuallyJarFile(dependency)) { -241 final File tdir = getNextTempDirectory(); -242 final String fileName = dependency.getFileName(); -243 -244 LOGGER.info(String.format("The zip file '%s' appears to be a JAR file, making a copy and analyzing it as a JAR.", fileName)); -245 -246 final File tmpLoc = new File(tdir, fileName.substring(0, fileName.length() - 3) + "jar"); -247 try { -248 org.apache.commons.io.FileUtils.copyFile(tdir, tmpLoc); -249 dependencies = new ArrayList<Dependency>(engine.getDependencies()); -250 engine.scan(tmpLoc); -251 newDependencies = engine.getDependencies(); -252 if (dependencies.size() != newDependencies.size()) { -253 //get the new dependencies -254 final Set<Dependency> dependencySet = new HashSet<Dependency>(); -255 dependencySet.addAll(newDependencies); -256 dependencySet.removeAll(dependencies); -257 if (dependencySet.size() != 1) { -258 LOGGER.info("Deep copy of ZIP to JAR file resulted in more then one dependency?"); -259 } -260 for (Dependency d : dependencySet) { -261 //fix the dependency's display name and path -262 d.setFilePath(dependency.getFilePath()); -263 d.setDisplayFileName(dependency.getFileName()); -264 } -265 } -266 } catch (IOException ex) { -267 final String msg = String.format("Unable to perform deep copy on '%s'", dependency.getActualFile().getPath()); -268 LOGGER.log(Level.FINE, msg, ex); -269 } -270 } -271 engine.getDependencies().remove(dependency); -272 } -273 Collections.sort(engine.getDependencies()); -274 } -275 -276 /** -277 * Retrieves the next temporary directory to extract an archive too. -278 * -279 * @return a directory -280 * @throws AnalysisException thrown if unable to create temporary directory -281 */ -282 private File getNextTempDirectory() throws AnalysisException { -283 dirCount += 1; -284 final File directory = new File(tempFileLocation, String.valueOf(dirCount)); -285 //getting an exception for some directories not being able to be created; might be because the directory already exists? -286 if (directory.exists()) { -287 return getNextTempDirectory(); -288 } -289 if (!directory.mkdirs()) { -290 final String msg = String.format("Unable to create temp directory '%s'.", directory.getAbsolutePath()); -291 throw new AnalysisException(msg); -292 } -293 return directory; -294 } -295 -296 /** -297 * Extracts the contents of an archive into the specified directory. -298 * -299 * @param archive an archive file such as a WAR or EAR -300 * @param destination a directory to extract the contents to -301 * @param engine the scanning engine -302 * @throws AnalysisException thrown if the archive is not found -303 */ -304 private void extractFiles(File archive, File destination, Engine engine) throws AnalysisException { -305 if (archive == null || destination == null) { -306 return; -307 } -308 -309 FileInputStream fis = null; -310 try { -311 fis = new FileInputStream(archive); -312 } catch (FileNotFoundException ex) { -313 LOGGER.log(Level.FINE, null, ex); -314 throw new AnalysisException("Archive file was not found.", ex); -315 } -316 final String archiveExt = FileUtils.getFileExtension(archive.getName()).toLowerCase(); +49 import org.owasp.dependencycheck.utils.FileFilterBuilder; +50 import org.owasp.dependencycheck.utils.FileUtils; +51 import org.owasp.dependencycheck.utils.Settings; +52 import org.slf4j.Logger; +53 import org.slf4j.LoggerFactory; +54 +55 /** +56 * <p> +57 * An analyzer that extracts files from archives and ensures any supported files contained within the archive are added to the +58 * dependency list.</p> +59 * +60 * @author Jeremy Long +61 */ +62 public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer { +63 +64 /** +65 * The logger. +66 */ +67 private static final Logger LOGGER = LoggerFactory.getLogger(ArchiveAnalyzer.class); +68 /** +69 * The buffer size to use when extracting files from the archive. +70 */ +71 private static final int BUFFER_SIZE = 4096; +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 * The parent directory for the individual directories per archive. +78 */ +79 private File tempFileLocation = null; +80 /** +81 * The max scan depth that the analyzer will recursively extract nested archives. +82 */ +83 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 private int scanDepth = 0; +88 +89 //<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer"> +90 /** +91 * The name of the analyzer. +92 */ +93 private static final String ANALYZER_NAME = "Archive Analyzer"; +94 /** +95 * The phase that this analyzer is intended to run in. +96 */ +97 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INITIAL; +98 /** +99 * The set of things we can handle with Zip methods +100 */ +101 private static final Set<String> ZIPPABLES = newHashSet("zip", "ear", "war", "jar", "sar", "apk", "nupkg"); +102 /** +103 * The set of file extensions supported by this analyzer. Note for developers, any additions to this list will need to be +104 * explicitly handled in extractFiles(). +105 */ +106 private static final Set<String> EXTENSIONS = newHashSet("tar", "gz", "tgz"); +107 +108 /** +109 * Detects files with extensions to remove from the engine's collection of dependencies. +110 */ +111 private static final FileFilter REMOVE_FROM_ANALYSIS = FileFilterBuilder.newInstance().addExtensions("zip", "tar", "gz", "tgz").build(); +112 +113 static { +114 final String additionalZipExt = Settings.getString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS); +115 if (additionalZipExt != null) { +116 final Set<String> ext = new HashSet<String>(Arrays.asList(additionalZipExt)); +117 ZIPPABLES.addAll(ext); +118 } +119 EXTENSIONS.addAll(ZIPPABLES); +120 } +121 +122 /** +123 * The file filter used to filter supported files. +124 */ +125 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(EXTENSIONS).build(); +126 +127 @Override +128 protected FileFilter getFileFilter() { +129 return FILTER; +130 } +131 +132 /** +133 * Detects files with .zip extension. +134 */ +135 private static final FileFilter ZIP_FILTER = FileFilterBuilder.newInstance().addExtensions("zip").build(); +136 +137 /** +138 * Returns the name of the analyzer. +139 * +140 * @return the name of the analyzer. +141 */ +142 @Override +143 public String getName() { +144 return ANALYZER_NAME; +145 } +146 +147 /** +148 * Returns the phase that the analyzer is intended to run in. +149 * +150 * @return the phase that the analyzer is intended to run in. +151 */ +152 @Override +153 public AnalysisPhase getAnalysisPhase() { +154 return ANALYSIS_PHASE; +155 } +156 //</editor-fold> +157 +158 /** +159 * Returns the key used in the properties file to reference the analyzer's enabled property. +160 * +161 * @return the analyzer's enabled property setting key +162 */ +163 @Override +164 protected String getAnalyzerEnabledSettingKey() { +165 return Settings.KEYS.ANALYZER_ARCHIVE_ENABLED; +166 } +167 +168 /** +169 * The initialize method does nothing for this Analyzer. +170 * +171 * @throws Exception is thrown if there is an exception deleting or creating temporary files +172 */ +173 @Override +174 public void initializeFileTypeAnalyzer() throws Exception { +175 final File baseDir = Settings.getTempDirectory(); +176 tempFileLocation = File.createTempFile("check", "tmp", baseDir); +177 if (!tempFileLocation.delete()) { +178 final String msg = String.format("Unable to delete temporary file '%s'.", tempFileLocation.getAbsolutePath()); +179 throw new AnalysisException(msg); +180 } +181 if (!tempFileLocation.mkdirs()) { +182 final String msg = String.format("Unable to create directory '%s'.", tempFileLocation.getAbsolutePath()); +183 throw new AnalysisException(msg); +184 } +185 } +186 +187 /** +188 * The close method deletes any temporary files and directories created during analysis. +189 * +190 * @throws Exception thrown if there is an exception deleting temporary files +191 */ +192 @Override +193 public void close() throws Exception { +194 if (tempFileLocation != null && tempFileLocation.exists()) { +195 LOGGER.debug("Attempting to delete temporary files"); +196 final boolean success = FileUtils.delete(tempFileLocation); +197 if (!success && tempFileLocation != null && tempFileLocation.exists() && tempFileLocation.list().length > 0) { +198 LOGGER.warn("Failed to delete some temporary files, see the log for more details"); +199 } +200 } +201 } +202 +203 /** +204 * Analyzes a given dependency. If the dependency is an archive, such as a WAR or EAR, the contents are extracted, scanned, +205 * and added to the list of dependencies within the engine. +206 * +207 * @param dependency the dependency to analyze +208 * @param engine the engine scanning +209 * @throws AnalysisException thrown if there is an analysis exception +210 */ +211 @Override +212 public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { +213 final File f = new File(dependency.getActualFilePath()); +214 final File tmpDir = getNextTempDirectory(); +215 extractFiles(f, tmpDir, engine); +216 +217 //make a copy +218 List<Dependency> dependencies = new ArrayList<Dependency>(engine.getDependencies()); +219 engine.scan(tmpDir); +220 List<Dependency> newDependencies = engine.getDependencies(); +221 if (dependencies.size() != newDependencies.size()) { +222 //get the new dependencies +223 final Set<Dependency> dependencySet = new HashSet<Dependency>(); +224 dependencySet.addAll(newDependencies); +225 dependencySet.removeAll(dependencies); +226 +227 for (Dependency d : dependencySet) { +228 //fix the dependency's display name and path +229 final String displayPath = String.format("%s%s", +230 dependency.getFilePath(), +231 d.getActualFilePath().substring(tmpDir.getAbsolutePath().length())); +232 final String displayName = String.format("%s: %s", +233 dependency.getFileName(), +234 d.getFileName()); +235 d.setFilePath(displayPath); +236 d.setFileName(displayName); +237 +238 //TODO - can we get more evidence from the parent? EAR contains module name, etc. +239 //analyze the dependency (i.e. extract files) if it is a supported type. +240 if (this.accept(d.getActualFile()) && scanDepth < MAX_SCAN_DEPTH) { +241 scanDepth += 1; +242 analyze(d, engine); +243 scanDepth -= 1; +244 } +245 } +246 } +247 if (REMOVE_FROM_ANALYSIS.accept(dependency.getActualFile())) { +248 if (ZIP_FILTER.accept(dependency.getActualFile()) && isZipFileActuallyJarFile(dependency)) { +249 final File tdir = getNextTempDirectory(); +250 final String fileName = dependency.getFileName(); +251 +252 LOGGER.info(String.format("The zip file '%s' appears to be a JAR file, making a copy and analyzing it as a JAR.", fileName)); +253 +254 final File tmpLoc = new File(tdir, fileName.substring(0, fileName.length() - 3) + "jar"); +255 try { +256 org.apache.commons.io.FileUtils.copyFile(tdir, tmpLoc); +257 dependencies = new ArrayList<Dependency>(engine.getDependencies()); +258 engine.scan(tmpLoc); +259 newDependencies = engine.getDependencies(); +260 if (dependencies.size() != newDependencies.size()) { +261 //get the new dependencies +262 final Set<Dependency> dependencySet = new HashSet<Dependency>(); +263 dependencySet.addAll(newDependencies); +264 dependencySet.removeAll(dependencies); +265 if (dependencySet.size() != 1) { +266 LOGGER.info("Deep copy of ZIP to JAR file resulted in more then one dependency?"); +267 } +268 for (Dependency d : dependencySet) { +269 //fix the dependency's display name and path +270 d.setFilePath(dependency.getFilePath()); +271 d.setDisplayFileName(dependency.getFileName()); +272 } +273 } +274 } catch (IOException ex) { +275 LOGGER.debug("Unable to perform deep copy on '{}'", dependency.getActualFile().getPath(), ex); +276 } +277 } +278 engine.getDependencies().remove(dependency); +279 } +280 Collections.sort(engine.getDependencies()); +281 } +282 +283 /** +284 * Retrieves the next temporary directory to extract an archive too. +285 * +286 * @return a directory +287 * @throws AnalysisException thrown if unable to create temporary directory +288 */ +289 private File getNextTempDirectory() throws AnalysisException { +290 dirCount += 1; +291 final File directory = new File(tempFileLocation, String.valueOf(dirCount)); +292 //getting an exception for some directories not being able to be created; might be because the directory already exists? +293 if (directory.exists()) { +294 return getNextTempDirectory(); +295 } +296 if (!directory.mkdirs()) { +297 final String msg = String.format("Unable to create temp directory '%s'.", directory.getAbsolutePath()); +298 throw new AnalysisException(msg); +299 } +300 return directory; +301 } +302 +303 /** +304 * Extracts the contents of an archive into the specified directory. +305 * +306 * @param archive an archive file such as a WAR or EAR +307 * @param destination a directory to extract the contents to +308 * @param engine the scanning engine +309 * @throws AnalysisException thrown if the archive is not found +310 */ +311 private void extractFiles(File archive, File destination, Engine engine) throws AnalysisException { +312 if (archive == null || destination == null) { +313 return; +314 } +315 +316 FileInputStream fis = null; 317 try { -318 if (ZIPPABLES.contains(archiveExt)) { -319 extractArchive(new ZipArchiveInputStream(new BufferedInputStream(fis)), destination, engine); -320 } else if ("tar".equals(archiveExt)) { -321 extractArchive(new TarArchiveInputStream(new BufferedInputStream(fis)), destination, engine); -322 } else if ("gz".equals(archiveExt) || "tgz".equals(archiveExt)) { -323 final String uncompressedName = GzipUtils.getUncompressedFilename(archive.getName()); -324 final String uncompressedExt = FileUtils.getFileExtension(uncompressedName).toLowerCase(); -325 if (engine.supportsExtension(uncompressedExt)) { -326 decompressFile(new GzipCompressorInputStream(new BufferedInputStream(fis)), new File(destination, uncompressedName)); -327 } -328 } -329 } catch (ArchiveExtractionException ex) { -330 final String msg = String.format("Exception extracting archive '%s'.", archive.getName()); -331 LOGGER.log(Level.WARNING, msg); -332 LOGGER.log(Level.FINE, null, ex); -333 } catch (IOException ex) { -334 final String msg = String.format("Exception reading archive '%s'.", archive.getName()); -335 LOGGER.log(Level.WARNING, msg); -336 LOGGER.log(Level.FINE, null, ex); -337 } finally { -338 try { -339 fis.close(); -340 } catch (IOException ex) { -341 LOGGER.log(Level.FINE, null, ex); -342 } -343 } -344 } -345 -346 /** -347 * Extracts files from an archive. -348 * -349 * @param input the archive to extract files from -350 * @param destination the location to write the files too -351 * @param engine the dependency-check engine -352 * @throws ArchiveExtractionException thrown if there is an exception extracting files from the archive -353 */ -354 private void extractArchive(ArchiveInputStream input, File destination, Engine engine) throws ArchiveExtractionException { -355 ArchiveEntry entry; -356 try { -357 while ((entry = input.getNextEntry()) != null) { -358 if (entry.isDirectory()) { -359 final File d = new File(destination, entry.getName()); -360 if (!d.exists()) { -361 if (!d.mkdirs()) { -362 final String msg = String.format("Unable to create directory '%s'.", d.getAbsolutePath()); -363 throw new AnalysisException(msg); -364 } -365 } -366 } else { -367 final File file = new File(destination, entry.getName()); -368 final String ext = FileUtils.getFileExtension(file.getName()); -369 if (engine.supportsExtension(ext)) { -370 final String extracting = String.format("Extracting '%s'", file.getPath()); -371 LOGGER.fine(extracting); -372 BufferedOutputStream bos = null; -373 FileOutputStream fos = null; -374 try { -375 final File parent = file.getParentFile(); -376 if (!parent.isDirectory()) { -377 if (!parent.mkdirs()) { -378 final String msg = String.format("Unable to build directory '%s'.", parent.getAbsolutePath()); -379 throw new AnalysisException(msg); -380 } -381 } -382 fos = new FileOutputStream(file); -383 bos = new BufferedOutputStream(fos, BUFFER_SIZE); -384 int count; -385 final byte[] data = new byte[BUFFER_SIZE]; -386 while ((count = input.read(data, 0, BUFFER_SIZE)) != -1) { -387 bos.write(data, 0, count); -388 } -389 bos.flush(); -390 } catch (FileNotFoundException ex) { -391 LOGGER.log(Level.FINE, null, ex); -392 final String msg = String.format("Unable to find file '%s'.", file.getName()); -393 throw new AnalysisException(msg, ex); -394 } catch (IOException ex) { -395 LOGGER.log(Level.FINE, null, ex); -396 final String msg = String.format("IO Exception while parsing file '%s'.", file.getName()); -397 throw new AnalysisException(msg, ex); -398 } finally { -399 if (bos != null) { -400 try { -401 bos.close(); -402 } catch (IOException ex) { -403 LOGGER.log(Level.FINEST, null, ex); -404 } -405 } -406 if (fos != null) { -407 try { -408 fos.close(); -409 } catch (IOException ex) { -410 LOGGER.log(Level.FINEST, null, ex); -411 } -412 } -413 } -414 } -415 } -416 } -417 } catch (IOException ex) { -418 throw new ArchiveExtractionException(ex); -419 } catch (Throwable ex) { -420 throw new ArchiveExtractionException(ex); -421 } finally { -422 if (input != null) { -423 try { -424 input.close(); -425 } catch (IOException ex) { -426 LOGGER.log(Level.FINEST, null, ex); -427 } -428 } -429 } -430 } -431 -432 /** -433 * Decompresses a file. -434 * -435 * @param inputStream the compressed file -436 * @param outputFile the location to write the decompressed file -437 * @throws ArchiveExtractionException thrown if there is an exception decompressing the file -438 */ -439 private void decompressFile(CompressorInputStream inputStream, File outputFile) throws ArchiveExtractionException { -440 final String msg = String.format("Decompressing '%s'", outputFile.getPath()); -441 LOGGER.fine(msg); -442 FileOutputStream out = null; -443 try { -444 out = new FileOutputStream(outputFile); -445 final byte[] buffer = new byte[BUFFER_SIZE]; -446 int n = 0; -447 while (-1 != (n = inputStream.read(buffer))) { -448 out.write(buffer, 0, n); -449 } -450 } catch (FileNotFoundException ex) { -451 LOGGER.log(Level.FINE, null, ex); -452 throw new ArchiveExtractionException(ex); -453 } catch (IOException ex) { -454 LOGGER.log(Level.FINE, null, ex); -455 throw new ArchiveExtractionException(ex); -456 } finally { -457 if (out != null) { -458 try { -459 out.close(); -460 } catch (IOException ex) { -461 LOGGER.log(Level.FINEST, null, ex); -462 } -463 } -464 } -465 } -466 -467 /** -468 * Attempts to determine if a zip file is actually a JAR file. -469 * -470 * @param dependency the dependency to check -471 * @return true if the dependency appears to be a JAR file; otherwise false -472 */ -473 private boolean isZipFileActuallyJarFile(Dependency dependency) { -474 boolean isJar = false; -475 ZipFile zip = null; -476 try { -477 zip = new ZipFile(dependency.getActualFilePath()); -478 if (zip.getEntry("META-INF/MANIFEST.MF") != null -479 || zip.getEntry("META-INF/maven") != null) { -480 final Enumeration<ZipArchiveEntry> entries = zip.getEntries(); -481 while (entries.hasMoreElements()) { -482 final ZipArchiveEntry entry = entries.nextElement(); -483 if (!entry.isDirectory()) { -484 final String name = entry.getName().toLowerCase(); -485 if (name.endsWith(".class")) { -486 isJar = true; -487 break; -488 } -489 } -490 } -491 } -492 } catch (IOException ex) { -493 LOGGER.log(Level.FINE, String.format("Unable to unzip zip file '%s'", dependency.getFilePath()), ex); -494 } finally { -495 ZipFile.closeQuietly(zip); -496 } -497 -498 return isJar; -499 } -500 } +318 fis = new FileInputStream(archive); +319 } catch (FileNotFoundException ex) { +320 LOGGER.debug("", ex); +321 throw new AnalysisException("Archive file was not found.", ex); +322 } +323 final String archiveExt = FileUtils.getFileExtension(archive.getName()).toLowerCase(); +324 try { +325 if (ZIPPABLES.contains(archiveExt)) { +326 extractArchive(new ZipArchiveInputStream(new BufferedInputStream(fis)), destination, engine); +327 } else if ("tar".equals(archiveExt)) { +328 extractArchive(new TarArchiveInputStream(new BufferedInputStream(fis)), destination, engine); +329 } else if ("gz".equals(archiveExt) || "tgz".equals(archiveExt)) { +330 final String uncompressedName = GzipUtils.getUncompressedFilename(archive.getName()); +331 final File f = new File(destination, uncompressedName); +332 if (engine.accept(f)) { +333 decompressFile(new GzipCompressorInputStream(new BufferedInputStream(fis)), f); +334 } +335 } +336 } catch (ArchiveExtractionException ex) { +337 LOGGER.warn("Exception extracting archive '{}'.", archive.getName()); +338 LOGGER.debug("", ex); +339 } catch (IOException ex) { +340 LOGGER.warn("Exception reading archive '{}'.", archive.getName()); +341 LOGGER.debug("", ex); +342 } finally { +343 try { +344 fis.close(); +345 } catch (IOException ex) { +346 LOGGER.debug("", ex); +347 } +348 } +349 } +350 +351 /** +352 * Extracts files from an archive. +353 * +354 * @param input the archive to extract files from +355 * @param destination the location to write the files too +356 * @param engine the dependency-check engine +357 * @throws ArchiveExtractionException thrown if there is an exception extracting files from the archive +358 */ +359 private void extractArchive(ArchiveInputStream input, File destination, Engine engine) throws ArchiveExtractionException { +360 ArchiveEntry entry; +361 try { +362 while ((entry = input.getNextEntry()) != null) { +363 if (entry.isDirectory()) { +364 final File d = new File(destination, entry.getName()); +365 if (!d.exists()) { +366 if (!d.mkdirs()) { +367 final String msg = String.format("Unable to create directory '%s'.", d.getAbsolutePath()); +368 throw new AnalysisException(msg); +369 } +370 } +371 } else { +372 final File file = new File(destination, entry.getName()); +373 if (engine.accept(file)) { +374 LOGGER.debug("Extracting '{}'", file.getPath()); +375 BufferedOutputStream bos = null; +376 FileOutputStream fos = null; +377 try { +378 final File parent = file.getParentFile(); +379 if (!parent.isDirectory()) { +380 if (!parent.mkdirs()) { +381 final String msg = String.format("Unable to build directory '%s'.", parent.getAbsolutePath()); +382 throw new AnalysisException(msg); +383 } +384 } +385 fos = new FileOutputStream(file); +386 bos = new BufferedOutputStream(fos, BUFFER_SIZE); +387 int count; +388 final byte[] data = new byte[BUFFER_SIZE]; +389 while ((count = input.read(data, 0, BUFFER_SIZE)) != -1) { +390 bos.write(data, 0, count); +391 } +392 bos.flush(); +393 } catch (FileNotFoundException ex) { +394 LOGGER.debug("", ex); +395 final String msg = String.format("Unable to find file '%s'.", file.getName()); +396 throw new AnalysisException(msg, ex); +397 } catch (IOException ex) { +398 LOGGER.debug("", ex); +399 final String msg = String.format("IO Exception while parsing file '%s'.", file.getName()); +400 throw new AnalysisException(msg, ex); +401 } finally { +402 if (bos != null) { +403 try { +404 bos.close(); +405 } catch (IOException ex) { +406 LOGGER.trace("", ex); +407 } +408 } +409 if (fos != null) { +410 try { +411 fos.close(); +412 } catch (IOException ex) { +413 LOGGER.trace("", ex); +414 } +415 } +416 } +417 } +418 } +419 } +420 } catch (IOException ex) { +421 throw new ArchiveExtractionException(ex); +422 } catch (Throwable ex) { +423 throw new ArchiveExtractionException(ex); +424 } finally { +425 if (input != null) { +426 try { +427 input.close(); +428 } catch (IOException ex) { +429 LOGGER.trace("", ex); +430 } +431 } +432 } +433 } +434 +435 /** +436 * Decompresses a file. +437 * +438 * @param inputStream the compressed file +439 * @param outputFile the location to write the decompressed file +440 * @throws ArchiveExtractionException thrown if there is an exception decompressing the file +441 */ +442 private void decompressFile(CompressorInputStream inputStream, File outputFile) throws ArchiveExtractionException { +443 LOGGER.debug("Decompressing '{}'", outputFile.getPath()); +444 FileOutputStream out = null; +445 try { +446 out = new FileOutputStream(outputFile); +447 final byte[] buffer = new byte[BUFFER_SIZE]; +448 int n = 0; +449 while (-1 != (n = inputStream.read(buffer))) { +450 out.write(buffer, 0, n); +451 } +452 } catch (FileNotFoundException ex) { +453 LOGGER.debug("", ex); +454 throw new ArchiveExtractionException(ex); +455 } catch (IOException ex) { +456 LOGGER.debug("", ex); +457 throw new ArchiveExtractionException(ex); +458 } finally { +459 if (out != null) { +460 try { +461 out.close(); +462 } catch (IOException ex) { +463 LOGGER.trace("", ex); +464 } +465 } +466 } +467 } +468 +469 /** +470 * Attempts to determine if a zip file is actually a JAR file. +471 * +472 * @param dependency the dependency to check +473 * @return true if the dependency appears to be a JAR file; otherwise false +474 */ +475 private boolean isZipFileActuallyJarFile(Dependency dependency) { +476 boolean isJar = false; +477 ZipFile zip = null; +478 try { +479 zip = new ZipFile(dependency.getActualFilePath()); +480 if (zip.getEntry("META-INF/MANIFEST.MF") != null +481 || zip.getEntry("META-INF/maven") != null) { +482 final Enumeration<ZipArchiveEntry> entries = zip.getEntries(); +483 while (entries.hasMoreElements()) { +484 final ZipArchiveEntry entry = entries.nextElement(); +485 if (!entry.isDirectory()) { +486 final String name = entry.getName().toLowerCase(); +487 if (name.endsWith(".class")) { +488 isJar = true; +489 break; +490 } +491 } +492 } +493 } +494 } catch (IOException ex) { +495 LOGGER.debug("Unable to unzip zip file '{}'", dependency.getFilePath(), ex); +496 } finally { +497 ZipFile.closeQuietly(zip); +498 } +499 +500 return isJar; +501 } +502 }
    diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AssemblyAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AssemblyAnalyzer.html index 99ea1f797..94fe7682b 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AssemblyAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AssemblyAnalyzer.html @@ -25,312 +25,329 @@ 17 */ 18 package org.owasp.dependencycheck.analyzer; 19 -20 import java.io.BufferedReader; -21 import java.io.File; -22 import java.io.FileOutputStream; -23 import java.io.IOException; -24 import java.io.InputStream; -25 import java.io.InputStreamReader; -26 import java.util.ArrayList; -27 import java.util.List; -28 import java.util.Set; -29 import java.util.logging.Level; -30 import java.util.logging.Logger; -31 import javax.xml.parsers.DocumentBuilder; -32 import javax.xml.parsers.DocumentBuilderFactory; -33 import javax.xml.xpath.XPath; -34 import javax.xml.xpath.XPathExpressionException; -35 import javax.xml.xpath.XPathFactory; -36 import org.owasp.dependencycheck.Engine; -37 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; -38 import org.owasp.dependencycheck.dependency.Confidence; -39 import org.owasp.dependencycheck.dependency.Dependency; -40 import org.owasp.dependencycheck.dependency.Evidence; -41 import org.owasp.dependencycheck.utils.Settings; -42 import org.w3c.dom.Document; -43 import org.xml.sax.SAXException; -44 -45 /** -46 * Analyzer for getting company, product, and version information from a .NET assembly. -47 * -48 * @author colezlaw -49 * -50 */ -51 public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer { -52 -53 /** -54 * The analyzer name -55 */ -56 private static final String ANALYZER_NAME = "Assembly Analyzer"; -57 /** -58 * The analysis phase -59 */ -60 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; -61 /** -62 * The list of supported extensions -63 */ -64 private static final Set<String> SUPPORTED_EXTENSIONS = newHashSet("dll", "exe"); -65 /** -66 * The temp value for GrokAssembly.exe -67 */ -68 private File grokAssemblyExe = null; -69 /** -70 * The DocumentBuilder for parsing the XML -71 */ -72 private DocumentBuilder builder; -73 /** -74 * Logger -75 */ -76 private static final Logger LOGGER = Logger.getLogger(AssemblyAnalyzer.class.getName(), "dependencycheck-resources"); -77 +20 import ch.qos.cal10n.IMessageConveyor; +21 import ch.qos.cal10n.MessageConveyor; +22 import java.io.BufferedReader; +23 import java.io.File; +24 import java.io.FileFilter; +25 import java.io.FileOutputStream; +26 import java.io.IOException; +27 import java.io.InputStream; +28 import java.io.InputStreamReader; +29 import org.owasp.dependencycheck.Engine; +30 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; +31 import org.owasp.dependencycheck.dependency.Confidence; +32 import org.owasp.dependencycheck.dependency.Dependency; +33 import org.owasp.dependencycheck.dependency.Evidence; +34 import org.owasp.dependencycheck.utils.FileFilterBuilder; +35 import org.owasp.dependencycheck.utils.Settings; +36 import org.slf4j.Logger; +37 import org.slf4j.LoggerFactory; +38 import org.w3c.dom.Document; +39 import org.xml.sax.SAXException; +40 +41 import javax.xml.parsers.DocumentBuilder; +42 import javax.xml.parsers.DocumentBuilderFactory; +43 import javax.xml.xpath.XPath; +44 import javax.xml.xpath.XPathExpressionException; +45 import javax.xml.xpath.XPathFactory; +46 import java.util.ArrayList; +47 import java.util.List; +48 import java.util.Locale; +49 +50 /** +51 * Analyzer for getting company, product, and version information from a .NET assembly. +52 * +53 * @author colezlaw +54 * +55 */ +56 public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer { +57 +58 /** +59 * The analyzer name +60 */ +61 private static final String ANALYZER_NAME = "Assembly Analyzer"; +62 /** +63 * The analysis phase +64 */ +65 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; +66 /** +67 * The list of supported extensions +68 */ +69 private static final String[] SUPPORTED_EXTENSIONS = {"dll", "exe"}; +70 /** +71 * The temp value for GrokAssembly.exe +72 */ +73 private File grokAssemblyExe = null; +74 /** +75 * The DocumentBuilder for parsing the XML +76 */ +77 private DocumentBuilder builder; 78 /** -79 * Builds the beginnings of a List for ProcessBuilder -80 * -81 * @return the list of arguments to begin populating the ProcessBuilder -82 */ -83 private List<String> buildArgumentList() { -84 // Use file.separator as a wild guess as to whether this is Windows -85 final List<String> args = new ArrayList<String>(); -86 if (!"\\".equals(System.getProperty("file.separator"))) { -87 if (Settings.getString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH) != null) { -88 args.add(Settings.getString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH)); -89 } else { -90 args.add("mono"); -91 } -92 } -93 args.add(grokAssemblyExe.getPath()); -94 -95 return args; -96 } -97 -98 /** -99 * Performs the analysis on a single Dependency. -100 * -101 * @param dependency the dependency to analyze -102 * @param engine the engine to perform the analysis under -103 * @throws AnalysisException if anything goes sideways -104 */ -105 @Override -106 public void analyzeFileType(Dependency dependency, Engine engine) -107 throws AnalysisException { -108 if (grokAssemblyExe == null) { -109 LOGGER.warning("analyzer.AssemblyAnalyzer.notdeployed"); -110 return; -111 } -112 -113 final List<String> args = buildArgumentList(); -114 args.add(dependency.getActualFilePath()); -115 final ProcessBuilder pb = new ProcessBuilder(args); -116 BufferedReader rdr = null; -117 Document doc = null; -118 try { -119 final Process proc = pb.start(); -120 // Try evacuating the error stream -121 rdr = new BufferedReader(new InputStreamReader(proc.getErrorStream(), "UTF-8")); -122 String line = null; -123 // CHECKSTYLE:OFF -124 while (rdr.ready() && (line = rdr.readLine()) != null) { -125 LOGGER.log(Level.WARNING, "analyzer.AssemblyAnalyzer.grokassembly.stderr", line); -126 } -127 // CHECKSTYLE:ON -128 int rc = 0; -129 doc = builder.parse(proc.getInputStream()); -130 -131 try { -132 rc = proc.waitFor(); -133 } catch (InterruptedException ie) { -134 return; +79 * Message Conveyer +80 */ +81 private static final IMessageConveyor MESSAGE_CONVERYOR = new MessageConveyor(Locale.getDefault()); +82 /** +83 * Logger +84 */ +85 private static final Logger LOGGER = LoggerFactory.getLogger(AssemblyAnalyzer.class); +86 +87 /** +88 * Builds the beginnings of a List for ProcessBuilder +89 * +90 * @return the list of arguments to begin populating the ProcessBuilder +91 */ +92 private List<String> buildArgumentList() { +93 // Use file.separator as a wild guess as to whether this is Windows +94 final List<String> args = new ArrayList<String>(); +95 if (!"\\".equals(System.getProperty("file.separator"))) { +96 if (Settings.getString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH) != null) { +97 args.add(Settings.getString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH)); +98 } else { +99 args.add("mono"); +100 } +101 } +102 args.add(grokAssemblyExe.getPath()); +103 +104 return args; +105 } +106 +107 /** +108 * Performs the analysis on a single Dependency. +109 * +110 * @param dependency the dependency to analyze +111 * @param engine the engine to perform the analysis under +112 * @throws AnalysisException if anything goes sideways +113 */ +114 @Override +115 public void analyzeFileType(Dependency dependency, Engine engine) +116 throws AnalysisException { +117 if (grokAssemblyExe == null) { +118 LOGGER.warn("GrokAssembly didn't get deployed"); +119 return; +120 } +121 +122 final List<String> args = buildArgumentList(); +123 args.add(dependency.getActualFilePath()); +124 final ProcessBuilder pb = new ProcessBuilder(args); +125 BufferedReader rdr = null; +126 Document doc = null; +127 try { +128 final Process proc = pb.start(); +129 // Try evacuating the error stream +130 rdr = new BufferedReader(new InputStreamReader(proc.getErrorStream(), "UTF-8")); +131 String line = null; +132 // CHECKSTYLE:OFF +133 while (rdr.ready() && (line = rdr.readLine()) != null) { +134 LOGGER.warn("Error from GrokAssembly: {}", line); 135 } -136 if (rc == 3) { -137 LOGGER.log(Level.FINE, "analyzer.AssemblyAnalyzer.notassembly", dependency.getActualFilePath()); -138 return; -139 } else if (rc != 0) { -140 LOGGER.log(Level.WARNING, "analyzer.AssemblyAnalyzer.grokassembly.rc", rc); -141 } -142 -143 final XPath xpath = XPathFactory.newInstance().newXPath(); -144 -145 // First, see if there was an error -146 final String error = xpath.evaluate("/assembly/error", doc); -147 if (error != null && !"".equals(error)) { -148 throw new AnalysisException(error); -149 } -150 -151 final String version = xpath.evaluate("/assembly/version", doc); -152 if (version != null) { -153 dependency.getVersionEvidence().addEvidence(new Evidence("grokassembly", "version", -154 version, Confidence.HIGHEST)); -155 } -156 -157 final String vendor = xpath.evaluate("/assembly/company", doc); -158 if (vendor != null) { -159 dependency.getVendorEvidence().addEvidence(new Evidence("grokassembly", "vendor", -160 vendor, Confidence.HIGH)); -161 } -162 -163 final String product = xpath.evaluate("/assembly/product", doc); -164 if (product != null) { -165 dependency.getProductEvidence().addEvidence(new Evidence("grokassembly", "product", -166 product, Confidence.HIGH)); -167 } -168 -169 } catch (IOException ioe) { -170 throw new AnalysisException(ioe); -171 } catch (SAXException saxe) { -172 throw new AnalysisException("Couldn't parse GrokAssembly result", saxe); -173 } catch (XPathExpressionException xpe) { -174 // This shouldn't happen -175 throw new AnalysisException(xpe); -176 } finally { -177 if (rdr != null) { -178 try { -179 rdr.close(); -180 } catch (IOException ex) { -181 LOGGER.log(Level.FINEST, "ignore", ex); -182 } -183 } -184 } -185 } -186 -187 /** -188 * Initialize the analyzer. In this case, extract GrokAssembly.exe to a temporary location. -189 * -190 * @throws Exception if anything goes wrong -191 */ -192 @Override -193 public void initializeFileTypeAnalyzer() throws Exception { -194 final File tempFile = File.createTempFile("GKA", ".exe", Settings.getTempDirectory()); -195 FileOutputStream fos = null; -196 InputStream is = null; -197 try { -198 fos = new FileOutputStream(tempFile); -199 is = AssemblyAnalyzer.class.getClassLoader().getResourceAsStream("GrokAssembly.exe"); -200 final byte[] buff = new byte[4096]; -201 int bread = -1; -202 while ((bread = is.read(buff)) >= 0) { -203 fos.write(buff, 0, bread); -204 } -205 grokAssemblyExe = tempFile; -206 // Set the temp file to get deleted when we're done -207 grokAssemblyExe.deleteOnExit(); -208 LOGGER.log(Level.FINE, "analyzer.AssemblyAnalyzer.grokassembly.deployed", grokAssemblyExe.getPath()); -209 } catch (IOException ioe) { -210 this.setEnabled(false); -211 LOGGER.log(Level.WARNING, "analyzer.AssemblyAnalyzer.grokassembly.notdeployed", ioe.getMessage()); -212 throw new AnalysisException("Could not extract GrokAssembly.exe", ioe); -213 } finally { -214 if (fos != null) { -215 try { -216 fos.close(); -217 } catch (Throwable e) { -218 LOGGER.fine("Error closing output stream"); -219 } -220 } -221 if (is != null) { -222 try { -223 is.close(); -224 } catch (Throwable e) { -225 LOGGER.fine("Error closing input stream"); -226 } -227 } -228 } -229 -230 // Now, need to see if GrokAssembly actually runs from this location. -231 final List<String> args = buildArgumentList(); -232 BufferedReader rdr = null; -233 try { -234 final ProcessBuilder pb = new ProcessBuilder(args); -235 final Process p = pb.start(); -236 // Try evacuating the error stream -237 rdr = new BufferedReader(new InputStreamReader(p.getErrorStream(), "UTF-8")); -238 // CHECKSTYLE:OFF -239 while (rdr.ready() && rdr.readLine() != null) { -240 // We expect this to complain -241 } -242 // CHECKSTYLE:ON -243 final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(p.getInputStream()); -244 final XPath xpath = XPathFactory.newInstance().newXPath(); -245 final String error = xpath.evaluate("/assembly/error", doc); -246 if (p.waitFor() != 1 || error == null || "".equals(error)) { -247 LOGGER.warning("An error occurred with the .NET AssemblyAnalyzer, please see the log for more details."); -248 LOGGER.fine("GrokAssembly.exe is not working properly"); -249 grokAssemblyExe = null; -250 this.setEnabled(false); -251 throw new AnalysisException("Could not execute .NET AssemblyAnalyzer"); -252 } -253 } catch (Throwable e) { -254 if (e instanceof AnalysisException) { -255 throw (AnalysisException) e; -256 } else { -257 LOGGER.warning("analyzer.AssemblyAnalyzer.grokassembly.initialization.failed"); -258 LOGGER.log(Level.FINE, "analyzer.AssemblyAnalyzer.grokassembly.initialization.message", e.getMessage()); -259 this.setEnabled(false); -260 throw new AnalysisException("An error occured with the .NET AssemblyAnalyzer", e); -261 } -262 } finally { -263 if (rdr != null) { -264 try { -265 rdr.close(); -266 } catch (IOException ex) { -267 LOGGER.log(Level.FINEST, "ignore", ex); -268 } -269 } -270 } -271 builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); -272 } -273 -274 @Override -275 public void close() throws Exception { -276 super.close(); -277 try { -278 if (grokAssemblyExe != null && !grokAssemblyExe.delete()) { -279 grokAssemblyExe.deleteOnExit(); +136 // CHECKSTYLE:ON +137 int rc = 0; +138 doc = builder.parse(proc.getInputStream()); +139 +140 try { +141 rc = proc.waitFor(); +142 } catch (InterruptedException ie) { +143 return; +144 } +145 if (rc == 3) { +146 LOGGER.debug("{} is not a .NET assembly or executable and as such cannot be analyzed by dependency-check", +147 dependency.getActualFilePath()); +148 return; +149 } else if (rc != 0) { +150 LOGGER.warn("Return code {} from GrokAssembly", rc); +151 } +152 +153 final XPath xpath = XPathFactory.newInstance().newXPath(); +154 +155 // First, see if there was an error +156 final String error = xpath.evaluate("/assembly/error", doc); +157 if (error != null && !"".equals(error)) { +158 throw new AnalysisException(error); +159 } +160 +161 final String version = xpath.evaluate("/assembly/version", doc); +162 if (version != null) { +163 dependency.getVersionEvidence().addEvidence(new Evidence("grokassembly", "version", +164 version, Confidence.HIGHEST)); +165 } +166 +167 final String vendor = xpath.evaluate("/assembly/company", doc); +168 if (vendor != null) { +169 dependency.getVendorEvidence().addEvidence(new Evidence("grokassembly", "vendor", +170 vendor, Confidence.HIGH)); +171 } +172 +173 final String product = xpath.evaluate("/assembly/product", doc); +174 if (product != null) { +175 dependency.getProductEvidence().addEvidence(new Evidence("grokassembly", "product", +176 product, Confidence.HIGH)); +177 } +178 +179 } catch (IOException ioe) { +180 throw new AnalysisException(ioe); +181 } catch (SAXException saxe) { +182 throw new AnalysisException("Couldn't parse GrokAssembly result", saxe); +183 } catch (XPathExpressionException xpe) { +184 // This shouldn't happen +185 throw new AnalysisException(xpe); +186 } finally { +187 if (rdr != null) { +188 try { +189 rdr.close(); +190 } catch (IOException ex) { +191 LOGGER.debug("ignore", ex); +192 } +193 } +194 } +195 } +196 +197 /** +198 * Initialize the analyzer. In this case, extract GrokAssembly.exe to a temporary location. +199 * +200 * @throws Exception if anything goes wrong +201 */ +202 @Override +203 public void initializeFileTypeAnalyzer() throws Exception { +204 final File tempFile = File.createTempFile("GKA", ".exe", Settings.getTempDirectory()); +205 FileOutputStream fos = null; +206 InputStream is = null; +207 try { +208 fos = new FileOutputStream(tempFile); +209 is = AssemblyAnalyzer.class.getClassLoader().getResourceAsStream("GrokAssembly.exe"); +210 final byte[] buff = new byte[4096]; +211 int bread = -1; +212 while ((bread = is.read(buff)) >= 0) { +213 fos.write(buff, 0, bread); +214 } +215 grokAssemblyExe = tempFile; +216 // Set the temp file to get deleted when we're done +217 grokAssemblyExe.deleteOnExit(); +218 LOGGER.debug("Extracted GrokAssembly.exe to {}", grokAssemblyExe.getPath()); +219 } catch (IOException ioe) { +220 this.setEnabled(false); +221 LOGGER.warn("Could not extract GrokAssembly.exe: {}", ioe.getMessage()); +222 throw new AnalysisException("Could not extract GrokAssembly.exe", ioe); +223 } finally { +224 if (fos != null) { +225 try { +226 fos.close(); +227 } catch (Throwable e) { +228 LOGGER.debug("Error closing output stream"); +229 } +230 } +231 if (is != null) { +232 try { +233 is.close(); +234 } catch (Throwable e) { +235 LOGGER.debug("Error closing input stream"); +236 } +237 } +238 } +239 +240 // Now, need to see if GrokAssembly actually runs from this location. +241 final List<String> args = buildArgumentList(); +242 BufferedReader rdr = null; +243 try { +244 final ProcessBuilder pb = new ProcessBuilder(args); +245 final Process p = pb.start(); +246 // Try evacuating the error stream +247 rdr = new BufferedReader(new InputStreamReader(p.getErrorStream(), "UTF-8")); +248 // CHECKSTYLE:OFF +249 while (rdr.ready() && rdr.readLine() != null) { +250 // We expect this to complain +251 } +252 // CHECKSTYLE:ON +253 final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(p.getInputStream()); +254 final XPath xpath = XPathFactory.newInstance().newXPath(); +255 final String error = xpath.evaluate("/assembly/error", doc); +256 if (p.waitFor() != 1 || error == null || "".equals(error)) { +257 LOGGER.warn("An error occurred with the .NET AssemblyAnalyzer, please see the log for more details."); +258 LOGGER.debug("GrokAssembly.exe is not working properly"); +259 grokAssemblyExe = null; +260 this.setEnabled(false); +261 throw new AnalysisException("Could not execute .NET AssemblyAnalyzer"); +262 } +263 } catch (Throwable e) { +264 if (e instanceof AnalysisException) { +265 throw (AnalysisException) e; +266 } else { +267 LOGGER.warn("An error occurred with the .NET AssemblyAnalyzer;\n" +268 + "this can be ignored unless you are scanning .NET DLLs. Please see the log for more details."); +269 LOGGER.debug("Could not execute GrokAssembly {}", e.getMessage()); +270 this.setEnabled(false); +271 throw new AnalysisException("An error occured with the .NET AssemblyAnalyzer", e); +272 } +273 } finally { +274 if (rdr != null) { +275 try { +276 rdr.close(); +277 } catch (IOException ex) { +278 LOGGER.trace("ignore", ex); +279 } 280 } -281 } catch (SecurityException se) { -282 LOGGER.fine("analyzer.AssemblyAnalyzer.grokassembly.notdeleted"); -283 } -284 } -285 -286 /** -287 * Gets the set of extensions supported by this analyzer. -288 * -289 * @return the list of supported extensions -290 */ -291 @Override -292 public Set<String> getSupportedExtensions() { -293 return SUPPORTED_EXTENSIONS; -294 } -295 -296 /** -297 * Gets this analyzer's name. -298 * -299 * @return the analyzer name -300 */ -301 @Override -302 public String getName() { -303 return ANALYZER_NAME; -304 } -305 -306 /** -307 * Returns the phase this analyzer runs under. -308 * -309 * @return the phase this runs under -310 */ -311 @Override -312 public AnalysisPhase getAnalysisPhase() { -313 return ANALYSIS_PHASE; -314 } -315 -316 /** -317 * Returns the key used in the properties file to reference the analyzer's enabled property. -318 * -319 * @return the analyzer's enabled property setting key -320 */ -321 @Override -322 protected String getAnalyzerEnabledSettingKey() { -323 return Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED; -324 } -325 } +281 } +282 builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); +283 } +284 +285 /** +286 * Removes resources used from the local file system. +287 * +288 * @throws Exception thrown if there is a problem closing the analyzer +289 */ +290 @Override +291 public void close() throws Exception { +292 super.close(); +293 try { +294 if (grokAssemblyExe != null && !grokAssemblyExe.delete()) { +295 grokAssemblyExe.deleteOnExit(); +296 } +297 } catch (SecurityException se) { +298 LOGGER.debug("Can't delete temporary GrokAssembly.exe"); +299 } +300 } +301 +302 /** +303 * The File Filter used to filter supported extensions. +304 */ +305 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions( +306 SUPPORTED_EXTENSIONS).build(); +307 +308 @Override +309 protected FileFilter getFileFilter() { +310 return FILTER; +311 } +312 +313 /** +314 * Gets this analyzer's name. +315 * +316 * @return the analyzer name +317 */ +318 @Override +319 public String getName() { +320 return ANALYZER_NAME; +321 } +322 +323 /** +324 * Returns the phase this analyzer runs under. +325 * +326 * @return the phase this runs under +327 */ +328 @Override +329 public AnalysisPhase getAnalysisPhase() { +330 return ANALYSIS_PHASE; +331 } +332 +333 /** +334 * Returns the key used in the properties file to reference the analyzer's enabled property. +335 * +336 * @return the analyzer's enabled property setting key +337 */ +338 @Override +339 protected String getAnalyzerEnabledSettingKey() { +340 return Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED; +341 } +342 }
    diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AutoconfAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AutoconfAnalyzer.html new file mode 100644 index 000000000..3e773c55c --- /dev/null +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/AutoconfAnalyzer.html @@ -0,0 +1,292 @@ + + + +AutoconfAnalyzer 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) 2015 Institute for Defense Analyses. All Rights Reserved.
    +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;
    +28  import org.owasp.dependencycheck.utils.UrlStringUtils;
    +29  
    +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 <dvisser@ida.org>
    +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> deps = new ArrayList<Dependency>(
    +177                     engine.getDependencies());
    +178             deps.remove(dependency);
    +179             engine.setDependencies(deps);
    +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 occured while reading dependency file.", e);
    +229         }
    +230         return contents;
    +231     }
    +232 
    +233     /**
    +234      * Gathers evidence from a given file
    +235      *
    +236      * @param dependency the dependency to add evidence to
    +237      * @param name the source of the evidence
    +238      * @param contents the evidence to analyze
    +239      */
    +240     private void gatherEvidence(Dependency dependency, final String name,
    +241             String contents) {
    +242         final Matcher matcher = AC_INIT_PATTERN.matcher(contents);
    +243         if (matcher.find()) {
    +244             final EvidenceCollection productEvidence = dependency
    +245                     .getProductEvidence();
    +246             productEvidence.addEvidence(name, "Package", matcher.group(1),
    +247                     Confidence.HIGHEST);
    +248             dependency.getVersionEvidence().addEvidence(name,
    +249                     "Package Version", matcher.group(2), Confidence.HIGHEST);
    +250             final EvidenceCollection vendorEvidence = dependency
    +251                     .getVendorEvidence();
    +252             if (null != matcher.group(3)) {
    +253                 vendorEvidence.addEvidence(name, "Bug report address",
    +254                         matcher.group(4), Confidence.HIGH);
    +255             }
    +256             if (null != matcher.group(5)) {
    +257                 productEvidence.addEvidence(name, "Tarname", matcher.group(6),
    +258                         Confidence.HIGH);
    +259             }
    +260             if (null != matcher.group(7)) {
    +261                 final String url = matcher.group(8);
    +262                 if (UrlStringUtils.isUrl(url)) {
    +263                     vendorEvidence.addEvidence(name, "URL", url,
    +264                             Confidence.HIGH);
    +265                 }
    +266             }
    +267         }
    +268     }
    +269 
    +270     /**
    +271      * Initializes the file type analyzer.
    +272      *
    +273      * @throws Exception thrown if there is an exception during initialization
    +274      */
    +275     @Override
    +276     protected void initializeFileTypeAnalyzer() throws Exception {
    +277         // No initialization needed.
    +278     }
    +279 }
    +
    +
    + + + diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/CMakeAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/CMakeAnalyzer.html new file mode 100644 index 000000000..73566e2e5 --- /dev/null +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/CMakeAnalyzer.html @@ -0,0 +1,229 @@ + + + +CMakeAnalyzer 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) 2015 Institute for Defense Analyses. All Rights Reserved.
    +17   */
    +18  package org.owasp.dependencycheck.analyzer;
    +19  
    +20  import org.apache.commons.io.FileUtils;
    +21  import org.apache.commons.lang.StringUtils;
    +22  import org.owasp.dependencycheck.Engine;
    +23  import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
    +24  import org.owasp.dependencycheck.dependency.Confidence;
    +25  import org.owasp.dependencycheck.dependency.Dependency;
    +26  import org.owasp.dependencycheck.utils.Checksum;
    +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.File;
    +33  import java.io.FileFilter;
    +34  import java.io.IOException;
    +35  import java.security.MessageDigest;
    +36  import java.security.NoSuchAlgorithmException;
    +37  import java.util.regex.Matcher;
    +38  import java.util.regex.Pattern;
    +39  
    +40  /**
    +41   * <p>
    +42   * Used to analyze CMake build files, and collect information that can be used to determine the associated CPE.</p>
    +43   * <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 <dvisser@ida.org>
    +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      private static final Pattern PROJECT = Pattern.compile(
    +66              "^ *project *\\([ \\n]*(\\w+)[ \\n]*.*?\\)", REGEX_OPTIONS);
    +67  
    +68      // Group 1: Product
    +69      // Group 2: Version
    +70      private static final Pattern SET_VERSION = Pattern
    +71              .compile(
    +72                      "^ *set\\s*\\(\\s*(\\w+)_version\\s+\"?(\\d+(?:\\.\\d+)+)[\\s\"]?\\)",
    +73                      REGEX_OPTIONS);
    +74  
    +75      /**
    +76       * Detects files that can be analyzed.
    +77       */
    +78      private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(".cmake")
    +79              .addFilenames("CMakeLists.txt").build();
    +80  
    +81      /**
    +82       * A reference to SHA1 message digest.
    +83       */
    +84      private static MessageDigest sha1 = null;
    +85  
    +86      static {
    +87          try {
    +88              sha1 = MessageDigest.getInstance("SHA1");
    +89          } catch (NoSuchAlgorithmException e) {
    +90              LOGGER.error(e.getMessage());
    +91          }
    +92      }
    +93  
    +94      /**
    +95       * Returns the name of the CMake analyzer.
    +96       *
    +97       * @return the name of the analyzer
    +98       *
    +99       */
    +100     @Override
    +101     public String getName() {
    +102         return "CMake Analyzer";
    +103     }
    +104 
    +105     /**
    +106      * Tell that we are used for information collection.
    +107      *
    +108      * @return INFORMATION_COLLECTION
    +109      */
    +110     @Override
    +111     public AnalysisPhase getAnalysisPhase() {
    +112         return AnalysisPhase.INFORMATION_COLLECTION;
    +113     }
    +114 
    +115     /**
    +116      * Returns the set of supported file extensions.
    +117      *
    +118      * @return the set of supported file extensions
    +119      */
    +120     @Override
    +121     protected FileFilter getFileFilter() {
    +122         return FILTER;
    +123     }
    +124 
    +125     /**
    +126      * No-op initializer implementation.
    +127      *
    +128      * @throws Exception never thrown
    +129      */
    +130     @Override
    +131     protected void initializeFileTypeAnalyzer() throws Exception {
    +132         // Nothing to do here.
    +133     }
    +134 
    +135     /**
    +136      * Analyzes python packages and adds evidence to the dependency.
    +137      *
    +138      * @param dependency the dependency being analyzed
    +139      * @param engine the engine being used to perform the scan
    +140      * @throws AnalysisException thrown if there is an unrecoverable error analyzing the dependency
    +141      */
    +142     @Override
    +143     protected void analyzeFileType(Dependency dependency, Engine engine)
    +144             throws AnalysisException {
    +145         final File file = dependency.getActualFile();
    +146         final String parentName = file.getParentFile().getName();
    +147         final String name = file.getName();
    +148         dependency.setDisplayFileName(String.format("%s%c%s", parentName, File.separatorChar, name));
    +149         String contents;
    +150         try {
    +151             contents = FileUtils.readFileToString(file).trim();
    +152         } catch (IOException e) {
    +153             throw new AnalysisException(
    +154                     "Problem occurred while reading dependency file.", e);
    +155         }
    +156 
    +157         if (StringUtils.isNotBlank(contents)) {
    +158             final Matcher m = PROJECT.matcher(contents);
    +159             int count = 0;
    +160             while (m.find()) {
    +161                 count++;
    +162                 LOGGER.debug(String.format(
    +163                         "Found project command match with %d groups: %s",
    +164                         m.groupCount(), m.group(0)));
    +165                 final String group = m.group(1);
    +166                 LOGGER.debug("Group 1: " + group);
    +167                 dependency.getProductEvidence().addEvidence(name, "Project",
    +168                         group, Confidence.HIGH);
    +169             }
    +170             LOGGER.debug(String.format("Found %d matches.", count));
    +171             analyzeSetVersionCommand(dependency, engine, contents);
    +172         }
    +173     }
    +174 
    +175     private void analyzeSetVersionCommand(Dependency dependency, Engine engine, String contents) {
    +176         final Dependency orig = dependency;
    +177         final Matcher m = SET_VERSION.matcher(contents);
    +178         int count = 0;
    +179         while (m.find()) {
    +180             count++;
    +181             LOGGER.debug(String.format(
    +182                     "Found project command match with %d groups: %s",
    +183                     m.groupCount(), m.group(0)));
    +184             String product = m.group(1);
    +185             final String version = m.group(2);
    +186             LOGGER.debug("Group 1: " + product);
    +187             LOGGER.debug("Group 2: " + version);
    +188             final String aliasPrefix = "ALIASOF_";
    +189             if (product.startsWith(aliasPrefix)) {
    +190                 product = product.replaceFirst(aliasPrefix, "");
    +191             }
    +192             if (count > 1) {
    +193                 //TODO - refactor so we do not assign to the parameter (checkstyle)
    +194                 dependency = new Dependency(orig.getActualFile());
    +195                 dependency.setDisplayFileName(String.format("%s:%s", orig.getDisplayFileName(), product));
    +196                 final String filePath = String.format("%s:%s", orig.getFilePath(), product);
    +197                 dependency.setFilePath(filePath);
    +198 
    +199                 // prevents coalescing into the dependency provided by engine
    +200                 dependency.setSha1sum(Checksum.getHex(sha1.digest(filePath.getBytes())));
    +201                 engine.getDependencies().add(dependency);
    +202             }
    +203             final String source = dependency.getDisplayFileName();
    +204             dependency.getProductEvidence().addEvidence(source, "Product",
    +205                     product, Confidence.MEDIUM);
    +206             dependency.getVersionEvidence().addEvidence(source, "Version",
    +207                     version, Confidence.MEDIUM);
    +208         }
    +209         LOGGER.debug(String.format("Found %d matches.", count));
    +210     }
    +211 
    +212     @Override
    +213     protected String getAnalyzerEnabledSettingKey() {
    +214         return Settings.KEYS.ANALYZER_CMAKE_ENABLED;
    +215     }
    +216 }
    +
    +
    + + + 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 fbb5cef52..ce4c77c18 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/CPEAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/CPEAnalyzer.html @@ -33,30 +33,30 @@ 25 import java.util.List; 26 import java.util.Set; 27 import java.util.StringTokenizer; -28 import java.util.logging.Level; -29 import java.util.logging.Logger; -30 import org.apache.lucene.document.Document; -31 import org.apache.lucene.index.CorruptIndexException; -32 import org.apache.lucene.queryparser.classic.ParseException; -33 import org.apache.lucene.search.ScoreDoc; -34 import org.apache.lucene.search.TopDocs; -35 import org.owasp.dependencycheck.Engine; -36 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; -37 import org.owasp.dependencycheck.data.cpe.CpeMemoryIndex; -38 import org.owasp.dependencycheck.data.cpe.Fields; -39 import org.owasp.dependencycheck.data.cpe.IndexEntry; -40 import org.owasp.dependencycheck.data.cpe.IndexException; -41 import org.owasp.dependencycheck.data.lucene.LuceneUtils; -42 import org.owasp.dependencycheck.data.nvdcve.CveDB; -43 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; -44 import org.owasp.dependencycheck.dependency.Confidence; -45 import org.owasp.dependencycheck.dependency.Dependency; -46 import org.owasp.dependencycheck.dependency.Evidence; -47 import org.owasp.dependencycheck.dependency.EvidenceCollection; -48 import org.owasp.dependencycheck.dependency.Identifier; -49 import org.owasp.dependencycheck.dependency.VulnerableSoftware; -50 import org.owasp.dependencycheck.utils.DependencyVersion; -51 import org.owasp.dependencycheck.utils.DependencyVersionUtil; +28 import org.apache.lucene.document.Document; +29 import org.apache.lucene.index.CorruptIndexException; +30 import org.apache.lucene.queryparser.classic.ParseException; +31 import org.apache.lucene.search.ScoreDoc; +32 import org.apache.lucene.search.TopDocs; +33 import org.owasp.dependencycheck.Engine; +34 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; +35 import org.owasp.dependencycheck.data.cpe.CpeMemoryIndex; +36 import org.owasp.dependencycheck.data.cpe.Fields; +37 import org.owasp.dependencycheck.data.cpe.IndexEntry; +38 import org.owasp.dependencycheck.data.cpe.IndexException; +39 import org.owasp.dependencycheck.data.lucene.LuceneUtils; +40 import org.owasp.dependencycheck.data.nvdcve.CveDB; +41 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; +42 import org.owasp.dependencycheck.dependency.Confidence; +43 import org.owasp.dependencycheck.dependency.Dependency; +44 import org.owasp.dependencycheck.dependency.Evidence; +45 import org.owasp.dependencycheck.dependency.EvidenceCollection; +46 import org.owasp.dependencycheck.dependency.Identifier; +47 import org.owasp.dependencycheck.dependency.VulnerableSoftware; +48 import org.owasp.dependencycheck.utils.DependencyVersion; +49 import org.owasp.dependencycheck.utils.DependencyVersionUtil; +50 import org.slf4j.Logger; +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 @@ -69,7 +69,7 @@ 61 /** 62 * The Logger. 63 */ -64 private static final Logger LOGGER = Logger.getLogger(CPEAnalyzer.class.getName()); +64 private static final Logger LOGGER = LoggerFactory.getLogger(CPEAnalyzer.class); 65 /** 66 * The maximum number of query results to return. 67 */ @@ -142,15 +142,15 @@ 134 * process. 135 */ 136 public void open() throws IOException, DatabaseException { -137 LOGGER.log(Level.FINE, "Opening the CVE Database"); +137 LOGGER.debug("Opening the CVE Database"); 138 cve = new CveDB(); 139 cve.open(); -140 LOGGER.log(Level.FINE, "Creating the Lucene CPE Index"); +140 LOGGER.debug("Creating the Lucene CPE Index"); 141 cpe = CpeMemoryIndex.getInstance(); 142 try { 143 cpe.open(cve); 144 } catch (IndexException ex) { -145 LOGGER.log(Level.FINE, "IndexException", ex); +145 LOGGER.debug("IndexException", ex); 146 throw new DatabaseException(ex); 147 } 148 } @@ -162,140 +162,140 @@ 154 public void close() { 155 if (cpe != null) { 156 cpe.close(); -157 } -158 if (cve != null) { -159 cve.close(); -160 } -161 } -162 -163 public boolean isOpen() { -164 return cpe != null && cpe.isOpen(); -165 } -166 -167 /** -168 * Searches the data store of CPE entries, trying to identify the CPE for the given dependency based on the evidence contained -169 * within. The dependency passed in is updated with any identified CPE values. -170 * -171 * @param dependency the dependency to search for CPE entries on. -172 * @throws CorruptIndexException is thrown when the Lucene index is corrupt. -173 * @throws IOException is thrown when an IOException occurs. -174 * @throws ParseException is thrown when the Lucene query cannot be parsed. -175 */ -176 protected void determineCPE(Dependency dependency) throws CorruptIndexException, IOException, ParseException { -177 //TODO test dojo-war against this. we shold get dojo-toolkit:dojo-toolkit AND dojo-toolkit:toolkit -178 String vendors = ""; -179 String products = ""; -180 for (Confidence confidence : Confidence.values()) { -181 if (dependency.getVendorEvidence().contains(confidence)) { -182 vendors = addEvidenceWithoutDuplicateTerms(vendors, dependency.getVendorEvidence(), confidence); -183 LOGGER.fine(String.format("vendor search: %s", vendors)); -184 } -185 if (dependency.getProductEvidence().contains(confidence)) { -186 products = addEvidenceWithoutDuplicateTerms(products, dependency.getProductEvidence(), confidence); -187 LOGGER.fine(String.format("product search: %s", products)); -188 } -189 if (!vendors.isEmpty() && !products.isEmpty()) { -190 final List<IndexEntry> entries = searchCPE(vendors, products, dependency.getProductEvidence().getWeighting(), -191 dependency.getVendorEvidence().getWeighting()); -192 if (entries == null) { -193 continue; -194 } -195 boolean identifierAdded = false; -196 for (IndexEntry e : entries) { -197 LOGGER.fine(String.format("Verifying entry: %s", e.toString())); -198 if (verifyEntry(e, dependency)) { -199 final String vendor = e.getVendor(); -200 final String product = e.getProduct(); -201 LOGGER.fine(String.format("identified vendor/product: %s/%s", vendor, product)); -202 identifierAdded |= determineIdentifiers(dependency, vendor, product, confidence); -203 } -204 } -205 if (identifierAdded) { -206 break; -207 } -208 } -209 } -210 } -211 -212 /** -213 * Returns the text created by concatenating the text and the values from the EvidenceCollection (filtered for a specific -214 * confidence). This attempts to prevent duplicate terms from being added.<br/<br/> Note, if the evidence is longer then 200 -215 * characters it will be truncated. -216 * -217 * @param text the base text. -218 * @param ec an EvidenceCollection -219 * @param confidenceFilter a Confidence level to filter the evidence by. -220 * @return the new evidence text -221 */ -222 private String addEvidenceWithoutDuplicateTerms(final String text, final EvidenceCollection ec, Confidence confidenceFilter) { -223 final String txt = (text == null) ? "" : text; -224 final StringBuilder sb = new StringBuilder(txt.length() + (20 * ec.size())); -225 sb.append(' ').append(txt).append(' '); -226 for (Evidence e : ec.iterator(confidenceFilter)) { -227 String value = e.getValue(); -228 -229 //hack to get around the fact that lucene does a really good job of recognizing domains and not -230 // splitting them. TODO - put together a better lucene analyzer specific to the domain. -231 if (value.startsWith("http://")) { -232 value = value.substring(7).replaceAll("\\.", " "); -233 } -234 if (value.startsWith("https://")) { -235 value = value.substring(8).replaceAll("\\.", " "); -236 } -237 if (sb.indexOf(" " + value + " ") < 0) { -238 sb.append(value).append(' '); -239 } -240 } -241 return sb.toString().trim(); -242 } -243 -244 /** -245 * <p> -246 * Searches the Lucene CPE index to identify possible CPE entries associated with the supplied vendor, product, and -247 * version.</p> -248 * -249 * <p> -250 * If either the vendorWeightings or productWeightings lists have been populated this data is used to add weighting factors to -251 * the search.</p> -252 * -253 * @param vendor the text used to search the vendor field -254 * @param product the text used to search the product field -255 * @param vendorWeightings a list of strings to use to add weighting factors to the vendor field -256 * @param productWeightings Adds a list of strings that will be used to add weighting factors to the product search -257 * @return a list of possible CPE values -258 */ -259 protected List<IndexEntry> searchCPE(String vendor, String product, -260 Set<String> vendorWeightings, Set<String> productWeightings) { -261 -262 final List<IndexEntry> ret = new ArrayList<IndexEntry>(MAX_QUERY_RESULTS); +157 cpe = null; +158 } +159 if (cve != null) { +160 cve.close(); +161 cve = null; +162 } +163 } +164 +165 public boolean isOpen() { +166 return cpe != null && cpe.isOpen(); +167 } +168 +169 /** +170 * Searches the data store of CPE entries, trying to identify the CPE for the given dependency based on the evidence contained +171 * within. The dependency passed in is updated with any identified CPE values. +172 * +173 * @param dependency the dependency to search for CPE entries on. +174 * @throws CorruptIndexException is thrown when the Lucene index is corrupt. +175 * @throws IOException is thrown when an IOException occurs. +176 * @throws ParseException is thrown when the Lucene query cannot be parsed. +177 */ +178 protected void determineCPE(Dependency dependency) throws CorruptIndexException, IOException, ParseException { +179 //TODO test dojo-war against this. we shold get dojo-toolkit:dojo-toolkit AND dojo-toolkit:toolkit +180 String vendors = ""; +181 String products = ""; +182 for (Confidence confidence : Confidence.values()) { +183 if (dependency.getVendorEvidence().contains(confidence)) { +184 vendors = addEvidenceWithoutDuplicateTerms(vendors, dependency.getVendorEvidence(), confidence); +185 LOGGER.debug("vendor search: {}", vendors); +186 } +187 if (dependency.getProductEvidence().contains(confidence)) { +188 products = addEvidenceWithoutDuplicateTerms(products, dependency.getProductEvidence(), confidence); +189 LOGGER.debug("product search: {}", products); +190 } +191 if (!vendors.isEmpty() && !products.isEmpty()) { +192 final List<IndexEntry> entries = searchCPE(vendors, products, dependency.getProductEvidence().getWeighting(), +193 dependency.getVendorEvidence().getWeighting()); +194 if (entries == null) { +195 continue; +196 } +197 boolean identifierAdded = false; +198 for (IndexEntry e : entries) { +199 LOGGER.debug("Verifying entry: {}", e); +200 if (verifyEntry(e, dependency)) { +201 final String vendor = e.getVendor(); +202 final String product = e.getProduct(); +203 LOGGER.debug("identified vendor/product: {}/{}", vendor, product); +204 identifierAdded |= determineIdentifiers(dependency, vendor, product, confidence); +205 } +206 } +207 if (identifierAdded) { +208 break; +209 } +210 } +211 } +212 } +213 +214 /** +215 * Returns the text created by concatenating the text and the values from the EvidenceCollection (filtered for a specific +216 * confidence). This attempts to prevent duplicate terms from being added.<br/<br/> Note, if the evidence is longer then 200 +217 * characters it will be truncated. +218 * +219 * @param text the base text. +220 * @param ec an EvidenceCollection +221 * @param confidenceFilter a Confidence level to filter the evidence by. +222 * @return the new evidence text +223 */ +224 private String addEvidenceWithoutDuplicateTerms(final String text, final EvidenceCollection ec, Confidence confidenceFilter) { +225 final String txt = (text == null) ? "" : text; +226 final StringBuilder sb = new StringBuilder(txt.length() + (20 * ec.size())); +227 sb.append(' ').append(txt).append(' '); +228 for (Evidence e : ec.iterator(confidenceFilter)) { +229 String value = e.getValue(); +230 +231 //hack to get around the fact that lucene does a really good job of recognizing domains and not +232 // splitting them. TODO - put together a better lucene analyzer specific to the domain. +233 if (value.startsWith("http://")) { +234 value = value.substring(7).replaceAll("\\.", " "); +235 } +236 if (value.startsWith("https://")) { +237 value = value.substring(8).replaceAll("\\.", " "); +238 } +239 if (sb.indexOf(" " + value + " ") < 0) { +240 sb.append(value).append(' '); +241 } +242 } +243 return sb.toString().trim(); +244 } +245 +246 /** +247 * <p> +248 * Searches the Lucene CPE index to identify possible CPE entries associated with the supplied vendor, product, and +249 * version.</p> +250 * +251 * <p> +252 * If either the vendorWeightings or productWeightings lists have been populated this data is used to add weighting factors to +253 * the search.</p> +254 * +255 * @param vendor the text used to search the vendor field +256 * @param product the text used to search the product field +257 * @param vendorWeightings a list of strings to use to add weighting factors to the vendor field +258 * @param productWeightings Adds a list of strings that will be used to add weighting factors to the product search +259 * @return a list of possible CPE values +260 */ +261 protected List<IndexEntry> searchCPE(String vendor, String product, +262 Set<String> vendorWeightings, Set<String> productWeightings) { 263 -264 final String searchString = buildSearch(vendor, product, vendorWeightings, productWeightings); -265 if (searchString == null) { -266 return ret; -267 } -268 try { -269 final TopDocs docs = cpe.search(searchString, MAX_QUERY_RESULTS); -270 for (ScoreDoc d : docs.scoreDocs) { -271 if (d.score >= 0.08) { -272 final Document doc = cpe.getDocument(d.doc); -273 final IndexEntry entry = new IndexEntry(); -274 entry.setVendor(doc.get(Fields.VENDOR)); -275 entry.setProduct(doc.get(Fields.PRODUCT)); -276 entry.setSearchScore(d.score); -277 if (!ret.contains(entry)) { -278 ret.add(entry); -279 } -280 } -281 } -282 return ret; -283 } catch (ParseException ex) { -284 final String msg = String.format("Unable to parse: %s", searchString); -285 LOGGER.log(Level.WARNING, "An error occured querying the CPE data. See the log for more details."); -286 LOGGER.log(Level.INFO, msg, ex); -287 } catch (IOException ex) { -288 final String msg = String.format("IO Error with search string: %s", searchString); -289 LOGGER.log(Level.WARNING, "An error occured reading CPE data. See the log for more details."); -290 LOGGER.log(Level.INFO, msg, ex); +264 final List<IndexEntry> ret = new ArrayList<IndexEntry>(MAX_QUERY_RESULTS); +265 +266 final String searchString = buildSearch(vendor, product, vendorWeightings, productWeightings); +267 if (searchString == null) { +268 return ret; +269 } +270 try { +271 final TopDocs docs = cpe.search(searchString, MAX_QUERY_RESULTS); +272 for (ScoreDoc d : docs.scoreDocs) { +273 if (d.score >= 0.08) { +274 final Document doc = cpe.getDocument(d.doc); +275 final IndexEntry entry = new IndexEntry(); +276 entry.setVendor(doc.get(Fields.VENDOR)); +277 entry.setProduct(doc.get(Fields.PRODUCT)); +278 entry.setSearchScore(d.score); +279 if (!ret.contains(entry)) { +280 ret.add(entry); +281 } +282 } +283 } +284 return ret; +285 } catch (ParseException ex) { +286 LOGGER.warn("An error occured querying the CPE data. See the log for more details."); +287 LOGGER.info("Unable to parse: {}", searchString, ex); +288 } catch (IOException ex) { +289 LOGGER.warn("An error occured reading CPE data. See the log for more details."); +290 LOGGER.info("IO Error with search string: {}", searchString, ex); 291 } 292 return null; 293 } @@ -414,359 +414,361 @@ 406 private boolean verifyEntry(final IndexEntry entry, final Dependency dependency) { 407 boolean isValid = false; 408 -409 if (collectionContainsString(dependency.getProductEvidence(), entry.getProduct()) -410 && collectionContainsString(dependency.getVendorEvidence(), entry.getVendor())) { -411 //&& collectionContainsVersion(dependency.getVersionEvidence(), entry.getVersion()) -412 isValid = true; -413 } -414 return isValid; -415 } -416 -417 /** -418 * Used to determine if the EvidenceCollection contains a specific string. -419 * -420 * @param ec an EvidenceCollection -421 * @param text the text to search for -422 * @return whether or not the EvidenceCollection contains the string -423 */ -424 private boolean collectionContainsString(EvidenceCollection ec, String text) { -425 //TODO - likely need to change the split... not sure if this will work for CPE with special chars -426 if (text == null) { -427 return false; -428 } -429 final String[] words = text.split("[\\s_-]"); -430 final List<String> list = new ArrayList<String>(); -431 String tempWord = null; -432 for (String word : words) { -433 /* -434 single letter words should be concatenated with the next word. -435 so { "m", "core", "sample" } -> { "mcore", "sample" } -436 */ -437 if (tempWord != null) { -438 list.add(tempWord + word); -439 tempWord = null; -440 } else if (word.length() <= 2) { -441 tempWord = word; -442 } else { -443 list.add(word); -444 } -445 } -446 if (tempWord != null) { -447 if (!list.isEmpty()) { -448 final String tmp = list.get(list.size() - 1) + tempWord; -449 list.add(tmp); -450 } else { -451 list.add(tempWord); -452 } -453 } -454 if (list.isEmpty()) { -455 return false; -456 } -457 boolean contains = true; -458 for (String word : list) { -459 contains &= ec.containsUsedString(word); -460 } -461 return contains; -462 } -463 -464 /** -465 * Analyzes a dependency and attempts to determine if there are any CPE identifiers for this dependency. -466 * -467 * @param dependency The Dependency to analyze. -468 * @param engine The analysis engine -469 * @throws AnalysisException is thrown if there is an issue analyzing the dependency. -470 */ -471 @Override -472 public void analyze(Dependency dependency, Engine engine) throws AnalysisException { -473 try { -474 determineCPE(dependency); -475 } catch (CorruptIndexException ex) { -476 throw new AnalysisException("CPE Index is corrupt.", ex); -477 } catch (IOException ex) { -478 throw new AnalysisException("Failure opening the CPE Index.", ex); -479 } catch (ParseException ex) { -480 throw new AnalysisException("Unable to parse the generated Lucene query for this dependency.", ex); -481 } -482 } -483 -484 /** -485 * Retrieves a list of CPE values from the CveDB based on the vendor and product passed in. The list is then validated to find -486 * only CPEs that are valid for the given dependency. It is possible that the CPE identified is a best effort "guess" based on -487 * the vendor, product, and version information. -488 * -489 * @param dependency the Dependency being analyzed -490 * @param vendor the vendor for the CPE being analyzed -491 * @param product the product for the CPE being analyzed -492 * @param currentConfidence the current confidence being used during analysis -493 * @return <code>true</code> if an identifier was added to the dependency; otherwise <code>false</code> -494 * @throws UnsupportedEncodingException is thrown if UTF-8 is not supported -495 */ -496 protected boolean determineIdentifiers(Dependency dependency, String vendor, String product, -497 Confidence currentConfidence) throws UnsupportedEncodingException { -498 final Set<VulnerableSoftware> cpes = cve.getCPEs(vendor, product); -499 DependencyVersion bestGuess = new DependencyVersion("-"); -500 Confidence bestGuessConf = null; -501 boolean hasBroadMatch = false; -502 final List<IdentifierMatch> collected = new ArrayList<IdentifierMatch>(); -503 for (Confidence conf : Confidence.values()) { -504 // if (conf.compareTo(currentConfidence) > 0) { -505 // break; -506 // } -507 for (Evidence evidence : dependency.getVersionEvidence().iterator(conf)) { -508 final DependencyVersion evVer = DependencyVersionUtil.parseVersion(evidence.getValue()); -509 if (evVer == null) { -510 continue; -511 } -512 for (VulnerableSoftware vs : cpes) { -513 DependencyVersion dbVer; -514 if (vs.getRevision() != null && !vs.getRevision().isEmpty()) { -515 dbVer = DependencyVersionUtil.parseVersion(vs.getVersion() + "." + vs.getRevision()); -516 } else { -517 dbVer = DependencyVersionUtil.parseVersion(vs.getVersion()); -518 } -519 if (dbVer == null) { //special case, no version specified - everything is vulnerable -520 hasBroadMatch = true; -521 final String url = String.format(NVD_SEARCH_URL, URLEncoder.encode(vs.getName(), "UTF-8")); -522 final IdentifierMatch match = new IdentifierMatch("cpe", vs.getName(), url, IdentifierConfidence.BROAD_MATCH, conf); -523 collected.add(match); -524 } else if (evVer.equals(dbVer)) { //yeah! exact match -525 final String url = String.format(NVD_SEARCH_URL, URLEncoder.encode(vs.getName(), "UTF-8")); -526 final IdentifierMatch match = new IdentifierMatch("cpe", vs.getName(), url, IdentifierConfidence.EXACT_MATCH, conf); -527 collected.add(match); -528 } else { -529 //TODO the following isn't quite right is it? need to think about this guessing game a bit more. -530 if (evVer.getVersionParts().size() <= dbVer.getVersionParts().size() -531 && evVer.matchesAtLeastThreeLevels(dbVer)) { -532 if (bestGuessConf == null || bestGuessConf.compareTo(conf) > 0) { -533 if (bestGuess.getVersionParts().size() < dbVer.getVersionParts().size()) { -534 bestGuess = dbVer; -535 bestGuessConf = conf; -536 } -537 } -538 } -539 } -540 } -541 if (bestGuessConf == null || bestGuessConf.compareTo(conf) > 0) { -542 if (bestGuess.getVersionParts().size() < evVer.getVersionParts().size()) { -543 bestGuess = evVer; -544 bestGuessConf = conf; -545 } -546 } -547 } -548 } -549 final String cpeName = String.format("cpe:/a:%s:%s:%s", vendor, product, bestGuess.toString()); -550 String url = null; -551 if (hasBroadMatch) { //if we have a broad match we can add the URL to the best guess. -552 final String cpeUrlName = String.format("cpe:/a:%s:%s", vendor, product); -553 url = String.format(NVD_SEARCH_URL, URLEncoder.encode(cpeUrlName, "UTF-8")); -554 } -555 if (bestGuessConf == null) { -556 bestGuessConf = Confidence.LOW; -557 } -558 final IdentifierMatch match = new IdentifierMatch("cpe", cpeName, url, IdentifierConfidence.BEST_GUESS, bestGuessConf); -559 collected.add(match); -560 -561 Collections.sort(collected); -562 final IdentifierConfidence bestIdentifierQuality = collected.get(0).getConfidence(); -563 final Confidence bestEvidenceQuality = collected.get(0).getEvidenceConfidence(); -564 boolean identifierAdded = false; -565 for (IdentifierMatch m : collected) { -566 if (bestIdentifierQuality.equals(m.getConfidence()) -567 && bestEvidenceQuality.equals(m.getEvidenceConfidence())) { -568 final Identifier i = m.getIdentifier(); -569 if (bestIdentifierQuality == IdentifierConfidence.BEST_GUESS) { -570 i.setConfidence(Confidence.LOW); -571 } else { -572 i.setConfidence(bestEvidenceQuality); -573 } -574 dependency.addIdentifier(i); -575 identifierAdded = true; -576 } -577 } -578 return identifierAdded; -579 } -580 -581 /** -582 * The confidence whether the identifier is an exact match, or a best guess. -583 */ -584 private enum IdentifierConfidence { -585 -586 /** -587 * An exact match for the CPE. -588 */ -589 EXACT_MATCH, -590 /** -591 * A best guess for the CPE. -592 */ -593 BEST_GUESS, -594 /** -595 * The entire vendor/product group must be added (without a guess at version) because there is a CVE with a VS that only -596 * specifies vendor/product. -597 */ -598 BROAD_MATCH -599 } -600 -601 /** -602 * A simple object to hold an identifier and carry information about the confidence in the identifier. -603 */ -604 private static class IdentifierMatch implements Comparable<IdentifierMatch> { -605 -606 /** -607 * Constructs an IdentifierMatch. -608 * -609 * @param type the type of identifier (such as CPE) -610 * @param value the value of the identifier -611 * @param url the URL of the identifier -612 * @param identifierConfidence the confidence in the identifier: best guess or exact match -613 * @param evidenceConfidence the confidence of the evidence used to find the identifier -614 */ -615 IdentifierMatch(String type, String value, String url, IdentifierConfidence identifierConfidence, Confidence evidenceConfidence) { -616 this.identifier = new Identifier(type, value, url); -617 this.confidence = identifierConfidence; -618 this.evidenceConfidence = evidenceConfidence; -619 } -620 //<editor-fold defaultstate="collapsed" desc="Property implementations: evidenceConfidence, confidence, identifier"> -621 /** -622 * The confidence in the evidence used to identify this match. -623 */ -624 private Confidence evidenceConfidence; -625 -626 /** -627 * Get the value of evidenceConfidence -628 * -629 * @return the value of evidenceConfidence -630 */ -631 public Confidence getEvidenceConfidence() { -632 return evidenceConfidence; -633 } -634 -635 /** -636 * Set the value of evidenceConfidence -637 * -638 * @param evidenceConfidence new value of evidenceConfidence -639 */ -640 public void setEvidenceConfidence(Confidence evidenceConfidence) { -641 this.evidenceConfidence = evidenceConfidence; -642 } -643 /** -644 * The confidence whether this is an exact match, or a best guess. -645 */ -646 private IdentifierConfidence confidence; -647 -648 /** -649 * Get the value of confidence. -650 * -651 * @return the value of confidence -652 */ -653 public IdentifierConfidence getConfidence() { -654 return confidence; -655 } -656 -657 /** -658 * Set the value of confidence. -659 * -660 * @param confidence new value of confidence -661 */ -662 public void setConfidence(IdentifierConfidence confidence) { -663 this.confidence = confidence; -664 } -665 /** -666 * The CPE identifier. -667 */ -668 private Identifier identifier; -669 -670 /** -671 * Get the value of identifier. -672 * -673 * @return the value of identifier -674 */ -675 public Identifier getIdentifier() { -676 return identifier; -677 } -678 -679 /** -680 * Set the value of identifier. -681 * -682 * @param identifier new value of identifier -683 */ -684 public void setIdentifier(Identifier identifier) { -685 this.identifier = identifier; -686 } -687 //</editor-fold> -688 //<editor-fold defaultstate="collapsed" desc="Standard implementations of toString, hashCode, and equals"> -689 -690 /** -691 * Standard toString() implementation. -692 * -693 * @return the string representation of the object -694 */ -695 @Override -696 public String toString() { -697 return "IdentifierMatch{" + "evidenceConfidence=" + evidenceConfidence -698 + ", confidence=" + confidence + ", identifier=" + identifier + '}'; -699 } -700 -701 /** -702 * Standard hashCode() implementation. -703 * -704 * @return the hashCode -705 */ -706 @Override -707 public int hashCode() { -708 int hash = 5; -709 hash = 97 * hash + (this.evidenceConfidence != null ? this.evidenceConfidence.hashCode() : 0); -710 hash = 97 * hash + (this.confidence != null ? this.confidence.hashCode() : 0); -711 hash = 97 * hash + (this.identifier != null ? this.identifier.hashCode() : 0); -712 return hash; -713 } -714 -715 /** -716 * Standard equals implementation. -717 * -718 * @param obj the object to compare -719 * @return true if the objects are equal, otherwise false -720 */ -721 @Override -722 public boolean equals(Object obj) { -723 if (obj == null) { -724 return false; -725 } -726 if (getClass() != obj.getClass()) { -727 return false; -728 } -729 final IdentifierMatch other = (IdentifierMatch) obj; -730 if (this.evidenceConfidence != other.evidenceConfidence) { -731 return false; -732 } -733 if (this.confidence != other.confidence) { -734 return false; -735 } -736 if (this.identifier != other.identifier && (this.identifier == null || !this.identifier.equals(other.identifier))) { -737 return false; -738 } -739 return true; -740 } -741 //</editor-fold> -742 -743 /** -744 * Standard implementation of compareTo that compares identifier confidence, evidence confidence, and then the identifier. -745 * -746 * @param o the IdentifierMatch to compare to -747 * @return the natural ordering of IdentifierMatch -748 */ -749 @Override -750 public int compareTo(IdentifierMatch o) { -751 int conf = this.confidence.compareTo(o.confidence); -752 if (conf == 0) { -753 conf = this.evidenceConfidence.compareTo(o.evidenceConfidence); -754 if (conf == 0) { -755 conf = identifier.compareTo(o.identifier); -756 } -757 } -758 return conf; -759 } -760 } -761 } +409 //TODO - does this nullify some of the fuzzy matching that happens in the lucene search? +410 // for instance CPE some-component and in the evidence we have SomeComponent. +411 if (collectionContainsString(dependency.getProductEvidence(), entry.getProduct()) +412 && collectionContainsString(dependency.getVendorEvidence(), entry.getVendor())) { +413 //&& collectionContainsVersion(dependency.getVersionEvidence(), entry.getVersion()) +414 isValid = true; +415 } +416 return isValid; +417 } +418 +419 /** +420 * Used to determine if the EvidenceCollection contains a specific string. +421 * +422 * @param ec an EvidenceCollection +423 * @param text the text to search for +424 * @return whether or not the EvidenceCollection contains the string +425 */ +426 private boolean collectionContainsString(EvidenceCollection ec, String text) { +427 //TODO - likely need to change the split... not sure if this will work for CPE with special chars +428 if (text == null) { +429 return false; +430 } +431 final String[] words = text.split("[\\s_-]"); +432 final List<String> list = new ArrayList<String>(); +433 String tempWord = null; +434 for (String word : words) { +435 /* +436 single letter words should be concatenated with the next word. +437 so { "m", "core", "sample" } -> { "mcore", "sample" } +438 */ +439 if (tempWord != null) { +440 list.add(tempWord + word); +441 tempWord = null; +442 } else if (word.length() <= 2) { +443 tempWord = word; +444 } else { +445 list.add(word); +446 } +447 } +448 if (tempWord != null) { +449 if (!list.isEmpty()) { +450 final String tmp = list.get(list.size() - 1) + tempWord; +451 list.add(tmp); +452 } else { +453 list.add(tempWord); +454 } +455 } +456 if (list.isEmpty()) { +457 return false; +458 } +459 boolean contains = true; +460 for (String word : list) { +461 contains &= ec.containsUsedString(word); +462 } +463 return contains; +464 } +465 +466 /** +467 * Analyzes a dependency and attempts to determine if there are any CPE identifiers for this dependency. +468 * +469 * @param dependency The Dependency to analyze. +470 * @param engine The analysis engine +471 * @throws AnalysisException is thrown if there is an issue analyzing the dependency. +472 */ +473 @Override +474 public void analyze(Dependency dependency, Engine engine) throws AnalysisException { +475 try { +476 determineCPE(dependency); +477 } catch (CorruptIndexException ex) { +478 throw new AnalysisException("CPE Index is corrupt.", ex); +479 } catch (IOException ex) { +480 throw new AnalysisException("Failure opening the CPE Index.", ex); +481 } catch (ParseException ex) { +482 throw new AnalysisException("Unable to parse the generated Lucene query for this dependency.", ex); +483 } +484 } +485 +486 /** +487 * Retrieves a list of CPE values from the CveDB based on the vendor and product passed in. The list is then validated to find +488 * only CPEs that are valid for the given dependency. It is possible that the CPE identified is a best effort "guess" based on +489 * the vendor, product, and version information. +490 * +491 * @param dependency the Dependency being analyzed +492 * @param vendor the vendor for the CPE being analyzed +493 * @param product the product for the CPE being analyzed +494 * @param currentConfidence the current confidence being used during analysis +495 * @return <code>true</code> if an identifier was added to the dependency; otherwise <code>false</code> +496 * @throws UnsupportedEncodingException is thrown if UTF-8 is not supported +497 */ +498 protected boolean determineIdentifiers(Dependency dependency, String vendor, String product, +499 Confidence currentConfidence) throws UnsupportedEncodingException { +500 final Set<VulnerableSoftware> cpes = cve.getCPEs(vendor, product); +501 DependencyVersion bestGuess = new DependencyVersion("-"); +502 Confidence bestGuessConf = null; +503 boolean hasBroadMatch = false; +504 final List<IdentifierMatch> collected = new ArrayList<IdentifierMatch>(); +505 for (Confidence conf : Confidence.values()) { +506 // if (conf.compareTo(currentConfidence) > 0) { +507 // break; +508 // } +509 for (Evidence evidence : dependency.getVersionEvidence().iterator(conf)) { +510 final DependencyVersion evVer = DependencyVersionUtil.parseVersion(evidence.getValue()); +511 if (evVer == null) { +512 continue; +513 } +514 for (VulnerableSoftware vs : cpes) { +515 DependencyVersion dbVer; +516 if (vs.getUpdate() != null && !vs.getUpdate().isEmpty()) { +517 dbVer = DependencyVersionUtil.parseVersion(vs.getVersion() + "." + vs.getUpdate()); +518 } else { +519 dbVer = DependencyVersionUtil.parseVersion(vs.getVersion()); +520 } +521 if (dbVer == null) { //special case, no version specified - everything is vulnerable +522 hasBroadMatch = true; +523 final String url = String.format(NVD_SEARCH_URL, URLEncoder.encode(vs.getName(), "UTF-8")); +524 final IdentifierMatch match = new IdentifierMatch("cpe", vs.getName(), url, IdentifierConfidence.BROAD_MATCH, conf); +525 collected.add(match); +526 } else if (evVer.equals(dbVer)) { //yeah! exact match +527 final String url = String.format(NVD_SEARCH_URL, URLEncoder.encode(vs.getName(), "UTF-8")); +528 final IdentifierMatch match = new IdentifierMatch("cpe", vs.getName(), url, IdentifierConfidence.EXACT_MATCH, conf); +529 collected.add(match); +530 } else { +531 //TODO the following isn't quite right is it? need to think about this guessing game a bit more. +532 if (evVer.getVersionParts().size() <= dbVer.getVersionParts().size() +533 && evVer.matchesAtLeastThreeLevels(dbVer)) { +534 if (bestGuessConf == null || bestGuessConf.compareTo(conf) > 0) { +535 if (bestGuess.getVersionParts().size() < dbVer.getVersionParts().size()) { +536 bestGuess = dbVer; +537 bestGuessConf = conf; +538 } +539 } +540 } +541 } +542 } +543 if (bestGuessConf == null || bestGuessConf.compareTo(conf) > 0) { +544 if (bestGuess.getVersionParts().size() < evVer.getVersionParts().size()) { +545 bestGuess = evVer; +546 bestGuessConf = conf; +547 } +548 } +549 } +550 } +551 final String cpeName = String.format("cpe:/a:%s:%s:%s", vendor, product, bestGuess.toString()); +552 String url = null; +553 if (hasBroadMatch) { //if we have a broad match we can add the URL to the best guess. +554 final String cpeUrlName = String.format("cpe:/a:%s:%s", vendor, product); +555 url = String.format(NVD_SEARCH_URL, URLEncoder.encode(cpeUrlName, "UTF-8")); +556 } +557 if (bestGuessConf == null) { +558 bestGuessConf = Confidence.LOW; +559 } +560 final IdentifierMatch match = new IdentifierMatch("cpe", cpeName, url, IdentifierConfidence.BEST_GUESS, bestGuessConf); +561 collected.add(match); +562 +563 Collections.sort(collected); +564 final IdentifierConfidence bestIdentifierQuality = collected.get(0).getConfidence(); +565 final Confidence bestEvidenceQuality = collected.get(0).getEvidenceConfidence(); +566 boolean identifierAdded = false; +567 for (IdentifierMatch m : collected) { +568 if (bestIdentifierQuality.equals(m.getConfidence()) +569 && bestEvidenceQuality.equals(m.getEvidenceConfidence())) { +570 final Identifier i = m.getIdentifier(); +571 if (bestIdentifierQuality == IdentifierConfidence.BEST_GUESS) { +572 i.setConfidence(Confidence.LOW); +573 } else { +574 i.setConfidence(bestEvidenceQuality); +575 } +576 dependency.addIdentifier(i); +577 identifierAdded = true; +578 } +579 } +580 return identifierAdded; +581 } +582 +583 /** +584 * The confidence whether the identifier is an exact match, or a best guess. +585 */ +586 private enum IdentifierConfidence { +587 +588 /** +589 * An exact match for the CPE. +590 */ +591 EXACT_MATCH, +592 /** +593 * A best guess for the CPE. +594 */ +595 BEST_GUESS, +596 /** +597 * The entire vendor/product group must be added (without a guess at version) because there is a CVE with a VS that only +598 * specifies vendor/product. +599 */ +600 BROAD_MATCH +601 } +602 +603 /** +604 * A simple object to hold an identifier and carry information about the confidence in the identifier. +605 */ +606 private static class IdentifierMatch implements Comparable<IdentifierMatch> { +607 +608 /** +609 * Constructs an IdentifierMatch. +610 * +611 * @param type the type of identifier (such as CPE) +612 * @param value the value of the identifier +613 * @param url the URL of the identifier +614 * @param identifierConfidence the confidence in the identifier: best guess or exact match +615 * @param evidenceConfidence the confidence of the evidence used to find the identifier +616 */ +617 IdentifierMatch(String type, String value, String url, IdentifierConfidence identifierConfidence, Confidence evidenceConfidence) { +618 this.identifier = new Identifier(type, value, url); +619 this.confidence = identifierConfidence; +620 this.evidenceConfidence = evidenceConfidence; +621 } +622 //<editor-fold defaultstate="collapsed" desc="Property implementations: evidenceConfidence, confidence, identifier"> +623 /** +624 * The confidence in the evidence used to identify this match. +625 */ +626 private Confidence evidenceConfidence; +627 +628 /** +629 * Get the value of evidenceConfidence +630 * +631 * @return the value of evidenceConfidence +632 */ +633 public Confidence getEvidenceConfidence() { +634 return evidenceConfidence; +635 } +636 +637 /** +638 * Set the value of evidenceConfidence +639 * +640 * @param evidenceConfidence new value of evidenceConfidence +641 */ +642 public void setEvidenceConfidence(Confidence evidenceConfidence) { +643 this.evidenceConfidence = evidenceConfidence; +644 } +645 /** +646 * The confidence whether this is an exact match, or a best guess. +647 */ +648 private IdentifierConfidence confidence; +649 +650 /** +651 * Get the value of confidence. +652 * +653 * @return the value of confidence +654 */ +655 public IdentifierConfidence getConfidence() { +656 return confidence; +657 } +658 +659 /** +660 * Set the value of confidence. +661 * +662 * @param confidence new value of confidence +663 */ +664 public void setConfidence(IdentifierConfidence confidence) { +665 this.confidence = confidence; +666 } +667 /** +668 * The CPE identifier. +669 */ +670 private Identifier identifier; +671 +672 /** +673 * Get the value of identifier. +674 * +675 * @return the value of identifier +676 */ +677 public Identifier getIdentifier() { +678 return identifier; +679 } +680 +681 /** +682 * Set the value of identifier. +683 * +684 * @param identifier new value of identifier +685 */ +686 public void setIdentifier(Identifier identifier) { +687 this.identifier = identifier; +688 } +689 //</editor-fold> +690 //<editor-fold defaultstate="collapsed" desc="Standard implementations of toString, hashCode, and equals"> +691 +692 /** +693 * Standard toString() implementation. +694 * +695 * @return the string representation of the object +696 */ +697 @Override +698 public String toString() { +699 return "IdentifierMatch{" + "evidenceConfidence=" + evidenceConfidence +700 + ", confidence=" + confidence + ", identifier=" + identifier + '}'; +701 } +702 +703 /** +704 * Standard hashCode() implementation. +705 * +706 * @return the hashCode +707 */ +708 @Override +709 public int hashCode() { +710 int hash = 5; +711 hash = 97 * hash + (this.evidenceConfidence != null ? this.evidenceConfidence.hashCode() : 0); +712 hash = 97 * hash + (this.confidence != null ? this.confidence.hashCode() : 0); +713 hash = 97 * hash + (this.identifier != null ? this.identifier.hashCode() : 0); +714 return hash; +715 } +716 +717 /** +718 * Standard equals implementation. +719 * +720 * @param obj the object to compare +721 * @return true if the objects are equal, otherwise false +722 */ +723 @Override +724 public boolean equals(Object obj) { +725 if (obj == null) { +726 return false; +727 } +728 if (getClass() != obj.getClass()) { +729 return false; +730 } +731 final IdentifierMatch other = (IdentifierMatch) obj; +732 if (this.evidenceConfidence != other.evidenceConfidence) { +733 return false; +734 } +735 if (this.confidence != other.confidence) { +736 return false; +737 } +738 if (this.identifier != other.identifier && (this.identifier == null || !this.identifier.equals(other.identifier))) { +739 return false; +740 } +741 return true; +742 } +743 //</editor-fold> +744 +745 /** +746 * Standard implementation of compareTo that compares identifier confidence, evidence confidence, and then the identifier. +747 * +748 * @param o the IdentifierMatch to compare to +749 * @return the natural ordering of IdentifierMatch +750 */ +751 @Override +752 public int compareTo(IdentifierMatch o) { +753 int conf = this.confidence.compareTo(o.confidence); +754 if (conf == 0) { +755 conf = this.evidenceConfidence.compareTo(o.evidenceConfidence); +756 if (conf == 0) { +757 conf = identifier.compareTo(o.identifier); +758 } +759 } +760 return conf; +761 } +762 } +763 }
    diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/CentralAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/CentralAnalyzer.html index fbb0491ca..d61ea95c5 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/CentralAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/CentralAnalyzer.html @@ -25,207 +25,207 @@ 17 */ 18 package org.owasp.dependencycheck.analyzer; 19 -20 import java.io.File; -21 import java.io.FileNotFoundException; -22 import java.io.IOException; -23 import java.net.URL; -24 import java.util.List; -25 import java.util.Set; -26 import java.util.logging.Level; -27 import java.util.logging.Logger; -28 import org.apache.commons.io.FileUtils; -29 import org.owasp.dependencycheck.Engine; -30 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; -31 import org.owasp.dependencycheck.data.central.CentralSearch; -32 import org.owasp.dependencycheck.data.nexus.MavenArtifact; -33 import org.owasp.dependencycheck.dependency.Confidence; -34 import org.owasp.dependencycheck.dependency.Dependency; -35 import org.owasp.dependencycheck.dependency.Evidence; -36 import org.owasp.dependencycheck.xml.pom.PomUtils; -37 import org.owasp.dependencycheck.utils.DownloadFailedException; -38 import org.owasp.dependencycheck.utils.Downloader; -39 import org.owasp.dependencycheck.utils.InvalidSettingException; -40 import org.owasp.dependencycheck.utils.Settings; -41 -42 /** -43 * Analyzer which will attempt to locate a dependency, and the GAV information, by querying Central for the dependency's SHA-1 -44 * digest. -45 * -46 * @author colezlaw -47 */ -48 public class CentralAnalyzer extends AbstractFileTypeAnalyzer { -49 -50 /** -51 * The logger. -52 */ -53 private static final Logger LOGGER = Logger.getLogger(CentralAnalyzer.class.getName()); -54 -55 /** -56 * The name of the analyzer. -57 */ -58 private static final String ANALYZER_NAME = "Central Analyzer"; -59 -60 /** -61 * The phase in which this analyzer runs. -62 */ -63 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; -64 -65 /** -66 * The types of files on which this will work. -67 */ -68 private static final Set<String> SUPPORTED_EXTENSIONS = newHashSet("jar"); -69 -70 /** -71 * The analyzer should be disabled if there are errors, so this is a flag to determine if such an error has occurred. -72 */ -73 private boolean errorFlag = false; -74 -75 /** -76 * The searcher itself. -77 */ -78 private CentralSearch searcher; -79 /** -80 * Field indicating if the analyzer is enabled. -81 */ -82 private final boolean enabled = checkEnabled(); -83 -84 /** -85 * Determine whether to enable this analyzer or not. -86 * -87 * @return whether the analyzer should be enabled -88 */ -89 @Override -90 public boolean isEnabled() { -91 return enabled; -92 } -93 -94 /** -95 * Determines if this analyzer is enabled. -96 * -97 * @return <code>true</code> if the analyzer is enabled; otherwise <code>false</code> -98 */ -99 private boolean checkEnabled() { -100 boolean retval = false; -101 -102 try { -103 if (Settings.getBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED)) { -104 if (!Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED) -105 || NexusAnalyzer.DEFAULT_URL.equals(Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL))) { -106 LOGGER.fine("Enabling the Central analyzer"); -107 retval = true; -108 } else { -109 LOGGER.info("Nexus analyzer is enabled, disabling the Central Analyzer"); -110 } -111 } else { -112 LOGGER.info("Central analyzer disabled"); -113 } -114 } catch (InvalidSettingException ise) { -115 LOGGER.warning("Invalid setting. Disabling the Central analyzer"); -116 } -117 return retval; -118 } -119 -120 /** -121 * Initializes the analyzer once before any analysis is performed. -122 * -123 * @throws Exception if there's an error during initialization -124 */ -125 @Override -126 public void initializeFileTypeAnalyzer() throws Exception { -127 LOGGER.fine("Initializing Central analyzer"); -128 LOGGER.fine(String.format("Central analyzer enabled: %s", isEnabled())); -129 if (isEnabled()) { -130 final String searchUrl = Settings.getString(Settings.KEYS.ANALYZER_CENTRAL_URL); -131 LOGGER.fine(String.format("Central Analyzer URL: %s", searchUrl)); -132 searcher = new CentralSearch(new URL(searchUrl)); -133 } -134 } -135 -136 /** -137 * Returns the analyzer's name. -138 * -139 * @return the name of the analyzer -140 */ -141 @Override -142 public String getName() { -143 return ANALYZER_NAME; -144 } -145 -146 /** -147 * Returns the key used in the properties file to to reference the analyzer's enabled property. -148 * -149 * @return the analyzer's enabled property setting key. -150 */ -151 @Override -152 protected String getAnalyzerEnabledSettingKey() { -153 return Settings.KEYS.ANALYZER_CENTRAL_ENABLED; -154 } -155 -156 /** -157 * Returns the analysis phase under which the analyzer runs. -158 * -159 * @return the phase under which the analyzer runs -160 */ -161 @Override -162 public AnalysisPhase getAnalysisPhase() { -163 return ANALYSIS_PHASE; -164 } -165 -166 /** -167 * Returns the extensions for which this Analyzer runs. -168 * -169 * @return the extensions for which this Analyzer runs +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.data.central.CentralSearch; +24 import org.owasp.dependencycheck.data.nexus.MavenArtifact; +25 import org.owasp.dependencycheck.dependency.Confidence; +26 import org.owasp.dependencycheck.dependency.Dependency; +27 import org.owasp.dependencycheck.dependency.Evidence; +28 import org.owasp.dependencycheck.xml.pom.PomUtils; +29 import org.slf4j.Logger; +30 import org.slf4j.LoggerFactory; +31 +32 import java.io.File; +33 import java.io.FileFilter; +34 import java.io.FileNotFoundException; +35 import java.io.IOException; +36 import java.net.URL; +37 import java.util.List; +38 import org.owasp.dependencycheck.utils.DownloadFailedException; +39 import org.owasp.dependencycheck.utils.Downloader; +40 import org.owasp.dependencycheck.utils.FileFilterBuilder; +41 import org.owasp.dependencycheck.utils.InvalidSettingException; +42 import org.owasp.dependencycheck.utils.Settings; +43 +44 /** +45 * Analyzer which will attempt to locate a dependency, and the GAV information, by querying Central for the dependency's SHA-1 +46 * digest. +47 * +48 * @author colezlaw +49 */ +50 public class CentralAnalyzer extends AbstractFileTypeAnalyzer { +51 +52 /** +53 * The logger. +54 */ +55 private static final Logger LOGGER = LoggerFactory.getLogger(CentralAnalyzer.class); +56 +57 /** +58 * The name of the analyzer. +59 */ +60 private static final String ANALYZER_NAME = "Central Analyzer"; +61 +62 /** +63 * The phase in which this analyzer runs. +64 */ +65 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; +66 +67 /** +68 * The types of files on which this will work. +69 */ +70 private static final String SUPPORTED_EXTENSIONS = "jar"; +71 +72 /** +73 * The analyzer should be disabled if there are errors, so this is a flag to determine if such an error has occurred. +74 */ +75 private boolean errorFlag = false; +76 +77 /** +78 * The searcher itself. +79 */ +80 private CentralSearch searcher; +81 /** +82 * Field indicating if the analyzer is enabled. +83 */ +84 private final boolean enabled = checkEnabled(); +85 +86 /** +87 * Determine whether to enable this analyzer or not. +88 * +89 * @return whether the analyzer should be enabled +90 */ +91 @Override +92 public boolean isEnabled() { +93 return enabled; +94 } +95 +96 /** +97 * Determines if this analyzer is enabled. +98 * +99 * @return <code>true</code> if the analyzer is enabled; otherwise <code>false</code> +100 */ +101 private boolean checkEnabled() { +102 boolean retval = false; +103 +104 try { +105 if (Settings.getBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED)) { +106 if (!Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED) +107 || NexusAnalyzer.DEFAULT_URL.equals(Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL))) { +108 LOGGER.debug("Enabling the Central analyzer"); +109 retval = true; +110 } else { +111 LOGGER.info("Nexus analyzer is enabled, disabling the Central Analyzer"); +112 } +113 } else { +114 LOGGER.info("Central analyzer disabled"); +115 } +116 } catch (InvalidSettingException ise) { +117 LOGGER.warn("Invalid setting. Disabling the Central analyzer"); +118 } +119 return retval; +120 } +121 +122 /** +123 * Initializes the analyzer once before any analysis is performed. +124 * +125 * @throws Exception if there's an error during initialization +126 */ +127 @Override +128 public void initializeFileTypeAnalyzer() throws Exception { +129 LOGGER.debug("Initializing Central analyzer"); +130 LOGGER.debug("Central analyzer enabled: {}", isEnabled()); +131 if (isEnabled()) { +132 final String searchUrl = Settings.getString(Settings.KEYS.ANALYZER_CENTRAL_URL); +133 LOGGER.debug("Central Analyzer URL: {}", searchUrl); +134 searcher = new CentralSearch(new URL(searchUrl)); +135 } +136 } +137 +138 /** +139 * Returns the analyzer's name. +140 * +141 * @return the name of the analyzer +142 */ +143 @Override +144 public String getName() { +145 return ANALYZER_NAME; +146 } +147 +148 /** +149 * Returns the key used in the properties file to to reference the analyzer's enabled property. +150 * +151 * @return the analyzer's enabled property setting key. +152 */ +153 @Override +154 protected String getAnalyzerEnabledSettingKey() { +155 return Settings.KEYS.ANALYZER_CENTRAL_ENABLED; +156 } +157 +158 /** +159 * Returns the analysis phase under which the analyzer runs. +160 * +161 * @return the phase under which the analyzer runs +162 */ +163 @Override +164 public AnalysisPhase getAnalysisPhase() { +165 return ANALYSIS_PHASE; +166 } +167 +168 /** +169 * The file filter used to determine which files this analyzer supports. 170 */ -171 @Override -172 public Set<String> getSupportedExtensions() { -173 return SUPPORTED_EXTENSIONS; -174 } -175 -176 /** -177 * Performs the analysis. -178 * -179 * @param dependency the dependency to analyze -180 * @param engine the engine -181 * @throws AnalysisException when there's an exception during analysis -182 */ -183 @Override -184 public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { -185 if (errorFlag || !isEnabled()) { -186 return; -187 } -188 -189 try { -190 final List<MavenArtifact> mas = searcher.searchSha1(dependency.getSha1sum()); -191 final Confidence confidence = mas.size() > 1 ? Confidence.HIGH : Confidence.HIGHEST; -192 for (MavenArtifact ma : mas) { -193 LOGGER.fine(String.format("Central analyzer found artifact (%s) for dependency (%s)", ma.toString(), dependency.getFileName())); -194 dependency.addAsEvidence("central", ma, confidence); -195 boolean pomAnalyzed = false; -196 for (Evidence e : dependency.getVendorEvidence()) { -197 if ("pom".equals(e.getSource())) { -198 pomAnalyzed = true; -199 break; -200 } -201 } -202 if (!pomAnalyzed && ma.getPomUrl() != null) { -203 File pomFile = null; -204 try { -205 final File baseDir = Settings.getTempDirectory(); -206 pomFile = File.createTempFile("pom", ".xml", baseDir); -207 if (!pomFile.delete()) { -208 final String msg = String.format("Unable to fetch pom.xml for %s from Central; " -209 + "this could result in undetected CPE/CVEs.", dependency.getFileName()); -210 LOGGER.warning(msg); -211 LOGGER.fine("Unable to delete temp file"); -212 } -213 LOGGER.fine(String.format("Downloading %s", ma.getPomUrl())); -214 Downloader.fetchFile(new URL(ma.getPomUrl()), pomFile); -215 PomUtils.analyzePOM(dependency, pomFile); -216 -217 } catch (DownloadFailedException ex) { -218 final String msg = String.format("Unable to download pom.xml for %s from Central; " -219 + "this could result in undetected CPE/CVEs.", dependency.getFileName()); -220 LOGGER.warning(msg); +171 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(SUPPORTED_EXTENSIONS).build(); +172 +173 @Override +174 protected FileFilter getFileFilter() { +175 return FILTER; +176 } +177 +178 /** +179 * Performs the analysis. +180 * +181 * @param dependency the dependency to analyze +182 * @param engine the engine +183 * @throws AnalysisException when there's an exception during analysis +184 */ +185 @Override +186 public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { +187 if (errorFlag || !isEnabled()) { +188 return; +189 } +190 +191 try { +192 final List<MavenArtifact> mas = searcher.searchSha1(dependency.getSha1sum()); +193 final Confidence confidence = mas.size() > 1 ? Confidence.HIGH : Confidence.HIGHEST; +194 for (MavenArtifact ma : mas) { +195 LOGGER.debug("Central analyzer found artifact ({}) for dependency ({})", ma.toString(), dependency.getFileName()); +196 dependency.addAsEvidence("central", ma, confidence); +197 boolean pomAnalyzed = false; +198 for (Evidence e : dependency.getVendorEvidence()) { +199 if ("pom".equals(e.getSource())) { +200 pomAnalyzed = true; +201 break; +202 } +203 } +204 if (!pomAnalyzed && ma.getPomUrl() != null) { +205 File pomFile = null; +206 try { +207 final File baseDir = Settings.getTempDirectory(); +208 pomFile = File.createTempFile("pom", ".xml", baseDir); +209 if (!pomFile.delete()) { +210 LOGGER.warn("Unable to fetch pom.xml for {} from Central; " +211 + "this could result in undetected CPE/CVEs.", dependency.getFileName()); +212 LOGGER.debug("Unable to delete temp file"); +213 } +214 LOGGER.debug("Downloading {}", ma.getPomUrl()); +215 Downloader.fetchFile(new URL(ma.getPomUrl()), pomFile); +216 PomUtils.analyzePOM(dependency, pomFile); +217 +218 } catch (DownloadFailedException ex) { +219 LOGGER.warn("Unable to download pom.xml for {} from Central; " +220 + "this could result in undetected CPE/CVEs.", dependency.getFileName()); 221 } finally { 222 if (pomFile != null && !FileUtils.deleteQuietly(pomFile)) { 223 pomFile.deleteOnExit(); @@ -235,16 +235,15 @@ 227 228 } 229 } catch (IllegalArgumentException iae) { -230 LOGGER.info(String.format("invalid sha1-hash on %s", dependency.getFileName())); +230 LOGGER.info("invalid sha1-hash on {}", dependency.getFileName()); 231 } catch (FileNotFoundException fnfe) { -232 LOGGER.fine(String.format("Artifact not found in repository: '%s", dependency.getFileName())); +232 LOGGER.debug("Artifact not found in repository: '{}", dependency.getFileName()); 233 } catch (IOException ioe) { -234 LOGGER.log(Level.FINE, "Could not connect to Central search", ioe); +234 LOGGER.debug("Could not connect to Central search", ioe); 235 errorFlag = true; 236 } 237 } -238 -239 } +238 }
    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 bdf1a5758..406003c9a 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzer.html @@ -30,96 +30,96 @@ 22 import java.util.Iterator; 23 import java.util.ListIterator; 24 import java.util.Set; -25 import java.util.logging.Level; -26 import java.util.logging.Logger; -27 import java.util.regex.Matcher; -28 import java.util.regex.Pattern; -29 import org.owasp.dependencycheck.Engine; -30 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; -31 import org.owasp.dependencycheck.dependency.Dependency; -32 import org.owasp.dependencycheck.dependency.Identifier; -33 import org.owasp.dependencycheck.utils.DependencyVersion; -34 import org.owasp.dependencycheck.utils.DependencyVersionUtil; -35 import org.owasp.dependencycheck.utils.LogUtils; -36 -37 /** -38 * <p> -39 * This analyzer ensures dependencies that should be grouped together, to remove excess noise from the report, are grouped. An -40 * example would be Spring, Spring Beans, Spring MVC, etc. If they are all for the same version and have the same relative path -41 * then these should be grouped into a single dependency under the core/main library.</p> -42 * <p> -43 * Note, this grouping only works on dependencies with identified CVE entries</p> -44 * -45 * @author Jeremy Long -46 */ -47 public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Analyzer { -48 -49 /** -50 * The Logger. -51 */ -52 private static final Logger LOGGER = Logger.getLogger(DependencyBundlingAnalyzer.class.getName()); -53 -54 //<editor-fold defaultstate="collapsed" desc="Constants and Member Variables"> -55 /** -56 * A pattern for obtaining the first part of a filename. -57 */ -58 private static final Pattern STARTING_TEXT_PATTERN = Pattern.compile("^[a-zA-Z0-9]*"); -59 /** -60 * a flag indicating if this analyzer has run. This analyzer only runs once. -61 */ -62 private boolean analyzed = false; -63 //</editor-fold> -64 //<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer"> -65 /** -66 * The name of the analyzer. -67 */ -68 private static final String ANALYZER_NAME = "Dependency Bundling Analyzer"; -69 /** -70 * The phase that this analyzer is intended to run in. -71 */ -72 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.PRE_FINDING_ANALYSIS; -73 -74 /** -75 * Returns the name of the analyzer. -76 * -77 * @return the name of the analyzer. -78 */ -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 public AnalysisPhase getAnalysisPhase() { -89 return ANALYSIS_PHASE; -90 } -91 //</editor-fold> -92 -93 /** -94 * Analyzes a set of dependencies. If they have been found to have the same base path and the same set of identifiers they are -95 * likely related. The related dependencies are bundled into a single reportable item. -96 * -97 * @param ignore this analyzer ignores the dependency being analyzed -98 * @param engine the engine that is scanning the dependencies -99 * @throws AnalysisException is thrown if there is an error reading the JAR file. -100 */ -101 @Override -102 public void analyze(Dependency ignore, Engine engine) throws AnalysisException { -103 if (!analyzed) { -104 analyzed = true; -105 final Set<Dependency> dependenciesToRemove = new HashSet<Dependency>(); -106 final ListIterator<Dependency> mainIterator = engine.getDependencies().listIterator(); -107 //for (Dependency nextDependency : engine.getDependencies()) { -108 while (mainIterator.hasNext()) { -109 final Dependency dependency = mainIterator.next(); -110 if (mainIterator.hasNext() && !dependenciesToRemove.contains(dependency)) { -111 final ListIterator<Dependency> subIterator = engine.getDependencies().listIterator(mainIterator.nextIndex()); -112 while (subIterator.hasNext()) { -113 final Dependency nextDependency = subIterator.next(); -114 if (hashesMatch(dependency, nextDependency)) { +25 import java.util.regex.Matcher; +26 import java.util.regex.Pattern; +27 import org.owasp.dependencycheck.Engine; +28 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; +29 import org.owasp.dependencycheck.dependency.Dependency; +30 import org.owasp.dependencycheck.dependency.Identifier; +31 import org.owasp.dependencycheck.utils.DependencyVersion; +32 import org.owasp.dependencycheck.utils.DependencyVersionUtil; +33 import org.slf4j.Logger; +34 import org.slf4j.LoggerFactory; +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 public String getName() { +79 return ANALYZER_NAME; +80 } +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 public AnalysisPhase getAnalysisPhase() { +88 return ANALYSIS_PHASE; +89 } +90 //</editor-fold> +91 +92 /** +93 * Analyzes a set of dependencies. If they have been found to have the same base path and the same set of identifiers they are +94 * likely related. The related dependencies are bundled into a single reportable item. +95 * +96 * @param ignore this analyzer ignores the dependency being analyzed +97 * @param engine the engine that is scanning the dependencies +98 * @throws AnalysisException is thrown if there is an error reading the JAR file. +99 */ +100 @Override +101 public void analyze(Dependency ignore, Engine engine) throws AnalysisException { +102 if (!analyzed) { +103 analyzed = true; +104 final Set<Dependency> dependenciesToRemove = new HashSet<Dependency>(); +105 final ListIterator<Dependency> mainIterator = engine.getDependencies().listIterator(); +106 //for (Dependency nextDependency : engine.getDependencies()) { +107 while (mainIterator.hasNext()) { +108 final Dependency dependency = mainIterator.next(); +109 if (mainIterator.hasNext() && !dependenciesToRemove.contains(dependency)) { +110 final ListIterator<Dependency> subIterator = engine.getDependencies().listIterator(mainIterator.nextIndex()); +111 while (subIterator.hasNext()) { +112 final Dependency nextDependency = subIterator.next(); +113 if (hashesMatch(dependency, nextDependency) && !containedInWar(dependency.getFilePath()) +114 && !containedInWar(nextDependency.getFilePath())) { 115 if (firstPathIsShortest(dependency.getFilePath(), nextDependency.getFilePath())) { 116 mergeDependencies(dependency, nextDependency, dependenciesToRemove); 117 } else { @@ -133,7 +133,7 @@ 125 break; 126 } else { 127 mergeDependencies(dependency, nextDependency, dependenciesToRemove); -128 nextDependency.getRelatedDependencies().remove(nextDependency); +128 dependency.getRelatedDependencies().remove(nextDependency); 129 } 130 } else if (cpeIdentifiersMatch(dependency, nextDependency) 131 && hasSameBasePath(dependency, nextDependency) @@ -270,166 +270,170 @@ 262 } 263 } 264 } -265 if (LogUtils.isVerboseLoggingEnabled()) { -266 final String msg = String.format("IdentifiersMatch=%s (%s, %s)", matches, dependency1.getFileName(), dependency2.getFileName()); -267 LOGGER.log(Level.FINE, msg); -268 } -269 return matches; -270 } -271 -272 /** -273 * Determines if the two dependencies have the same base path. -274 * -275 * @param dependency1 a Dependency object -276 * @param dependency2 a Dependency object -277 * @return true if the base paths of the dependencies are identical -278 */ -279 private boolean hasSameBasePath(Dependency dependency1, Dependency dependency2) { -280 if (dependency1 == null || dependency2 == null) { -281 return false; -282 } -283 final File lFile = new File(dependency1.getFilePath()); -284 String left = lFile.getParent(); -285 final File rFile = new File(dependency2.getFilePath()); -286 String right = rFile.getParent(); -287 if (left == null) { -288 return right == null; +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.equalsIgnoreCase(right)) { -291 return true; -292 } -293 if (left.matches(".*[/\\\\]repository[/\\\\].*") && right.matches(".*[/\\\\]repository[/\\\\].*")) { -294 left = getBaseRepoPath(left); -295 right = getBaseRepoPath(right); +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 if (left.equalsIgnoreCase(right)) { -298 return true; -299 } -300 //new code -301 for (Dependency child : dependency2.getRelatedDependencies()) { -302 if (hasSameBasePath(dependency1, child)) { -303 return true; -304 } -305 } -306 return false; -307 } -308 -309 /** -310 * This is likely a very broken attempt at determining if the 'left' dependency is the 'core' library in comparison to the -311 * 'right' library. -312 * -313 * @param left the dependency to test -314 * @param right the dependency to test against -315 * @return a boolean indicating whether or not the left dependency should be considered the "core" version. -316 */ -317 boolean isCore(Dependency left, Dependency right) { -318 final String leftName = left.getFileName().toLowerCase(); -319 final String rightName = right.getFileName().toLowerCase(); -320 -321 final boolean returnVal; -322 if (!rightName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+") && leftName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+") -323 || rightName.contains("core") && !leftName.contains("core") -324 || rightName.contains("kernel") && !leftName.contains("kernel")) { -325 returnVal = false; -326 } else if (rightName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+") && !leftName.matches(".*\\.(tar|tgz|gz|zip|ear|war).+") -327 || !rightName.contains("core") && leftName.contains("core") -328 || !rightName.contains("kernel") && leftName.contains("kernel")) { -329 returnVal = true; -330 // } else if (leftName.matches(".*struts2\\-core.*") && rightName.matches(".*xwork\\-core.*")) { -331 // returnVal = true; -332 // } else if (rightName.matches(".*struts2\\-core.*") && leftName.matches(".*xwork\\-core.*")) { -333 // returnVal = false; -334 } else { -335 /* -336 * considered splitting the names up and comparing the components, -337 * but decided that the file name length should be sufficient as the -338 * "core" component, if this follows a normal naming protocol should -339 * be shorter: -340 * axis2-saaj-1.4.1.jar -341 * axis2-1.4.1.jar <----- -342 * axis2-kernel-1.4.1.jar -343 */ -344 returnVal = leftName.length() <= rightName.length(); -345 } -346 if (LogUtils.isVerboseLoggingEnabled()) { -347 final String msg = String.format("IsCore=%s (%s, %s)", returnVal, left.getFileName(), right.getFileName()); -348 LOGGER.log(Level.FINE, msg); -349 } -350 return returnVal; -351 } -352 -353 /** -354 * Compares the SHA1 hashes of two dependencies to determine if they are equal. -355 * -356 * @param dependency1 a dependency object to compare -357 * @param dependency2 a dependency object to compare -358 * @return true if the sha1 hashes of the two dependencies match; otherwise false -359 */ -360 private boolean hashesMatch(Dependency dependency1, Dependency dependency2) { -361 if (dependency1 == null || dependency2 == null || dependency1.getSha1sum() == null || dependency2.getSha1sum() == null) { -362 return false; -363 } -364 return dependency1.getSha1sum().equals(dependency2.getSha1sum()); -365 } -366 -367 /** -368 * Determines if the jar is shaded and the created pom.xml identified the same CPE as the jar - if so, the pom.xml dependency -369 * should be removed. -370 * -371 * @param dependency a dependency to check -372 * @param nextDependency another dependency to check -373 * @return true if on of the dependencies is a pom.xml and the identifiers between the two collections match; otherwise false -374 */ -375 private boolean isShadedJar(Dependency dependency, Dependency nextDependency) { -376 final String mainName = dependency.getFileName().toLowerCase(); -377 final String nextName = nextDependency.getFileName().toLowerCase(); -378 if (mainName.endsWith(".jar") && nextName.endsWith("pom.xml")) { -379 return dependency.getIdentifiers().containsAll(nextDependency.getIdentifiers()); -380 } else if (nextName.endsWith(".jar") && mainName.endsWith("pom.xml")) { -381 return nextDependency.getIdentifiers().containsAll(dependency.getIdentifiers()); -382 } -383 return false; -384 } -385 -386 /** -387 * Determines which path is shortest; if path lengths are equal then we use compareTo of the string method to determine if the -388 * first path is smaller. -389 * -390 * @param left the first path to compare -391 * @param right the second path to compare -392 * @return <code>true</code> if the leftPath is the shortest; otherwise <code>false</code> -393 */ -394 protected boolean firstPathIsShortest(String left, String right) { -395 final String leftPath = left.replace('\\', '/'); -396 final String rightPath = right.replace('\\', '/'); -397 -398 final int leftCount = countChar(leftPath, '/'); -399 final int rightCount = countChar(rightPath, '/'); -400 if (leftCount == rightCount) { -401 return leftPath.compareTo(rightPath) <= 0; -402 } else { -403 return leftCount < rightCount; -404 } -405 } -406 -407 /** -408 * Counts the number of times the character is present in the string. -409 * -410 * @param string the string to count the characters in -411 * @param c the character to count -412 * @return the number of times the character is present in the string -413 */ -414 private int countChar(String string, char c) { -415 int count = 0; -416 final int max = string.length(); -417 for (int i = 0; i < max; i++) { -418 if (c == string.charAt(i)) { -419 count++; -420 } -421 } -422 return count; -423 } -424 } +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(); +342 } +343 LOGGER.debug("IsCore={} ({}, {})", returnVal, left.getFileName(), right.getFileName()); +344 return returnVal; +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> +387 */ +388 protected boolean firstPathIsShortest(String left, String right) { +389 final String leftPath = left.replace('\\', '/'); +390 final String rightPath = right.replace('\\', '/'); +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 }
    diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/FalsePositiveAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/FalsePositiveAnalyzer.html index 56380a61e..37e338928 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/FalsePositiveAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/FalsePositiveAnalyzer.html @@ -25,455 +25,471 @@ 17 */ 18 package org.owasp.dependencycheck.analyzer; 19 -20 import java.io.UnsupportedEncodingException; -21 import java.net.URLEncoder; -22 import java.util.ArrayList; -23 import java.util.Collections; -24 import java.util.Iterator; -25 import java.util.List; -26 import java.util.ListIterator; -27 import java.util.Set; -28 import java.util.logging.Level; -29 import java.util.logging.Logger; -30 import java.util.regex.Matcher; -31 import java.util.regex.Pattern; -32 import org.owasp.dependencycheck.Engine; -33 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; -34 import org.owasp.dependencycheck.dependency.Dependency; -35 import org.owasp.dependencycheck.dependency.Identifier; -36 import org.owasp.dependencycheck.dependency.VulnerableSoftware; -37 -38 /** -39 * This analyzer attempts to remove some well known false positives - specifically regarding the java runtime. -40 * -41 * @author Jeremy Long -42 */ -43 public class FalsePositiveAnalyzer extends AbstractAnalyzer { -44 -45 /** -46 * The Logger. -47 */ -48 private static final Logger LOGGER = Logger.getLogger(FalsePositiveAnalyzer.class.getName()); -49 //<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer"> -50 /** -51 * The name of the analyzer. -52 */ -53 private static final String ANALYZER_NAME = "False Positive Analyzer"; -54 /** -55 * The phase that this analyzer is intended to run in. -56 */ -57 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.POST_IDENTIFIER_ANALYSIS; -58 -59 /** -60 * Returns the name of the analyzer. -61 * -62 * @return the name of the analyzer. -63 */ -64 public String getName() { -65 return ANALYZER_NAME; -66 } -67 -68 /** -69 * Returns the phase that the analyzer is intended to run in. -70 * -71 * @return the phase that the analyzer is intended to run in. -72 */ -73 public AnalysisPhase getAnalysisPhase() { -74 return ANALYSIS_PHASE; -75 } -76 //</editor-fold> -77 -78 /** -79 * Analyzes the dependencies and removes bad/incorrect CPE associations based on various heuristics. -80 * -81 * @param dependency the dependency to analyze. -82 * @param engine the engine that is scanning the dependencies -83 * @throws AnalysisException is thrown if there is an error reading the JAR file. -84 */ -85 @Override -86 public void analyze(Dependency dependency, Engine engine) throws AnalysisException { -87 removeJreEntries(dependency); -88 removeBadMatches(dependency); -89 removeBadSpringMatches(dependency); -90 removeWrongVersionMatches(dependency); -91 removeSpuriousCPE(dependency); -92 removeDuplicativeEntriesFromJar(dependency, engine); -93 addFalseNegativeCPEs(dependency); -94 } -95 -96 /** -97 * Removes inaccurate matches on springframework CPEs. -98 * -99 * @param dependency the dependency to test for and remove known inaccurate CPE matches -100 */ -101 private void removeBadSpringMatches(Dependency dependency) { -102 String mustContain = null; -103 for (Identifier i : dependency.getIdentifiers()) { -104 if ("maven".contains(i.getType())) { -105 if (i.getValue() != null && i.getValue().startsWith("org.springframework.")) { -106 final int endPoint = i.getValue().indexOf(":", 19); -107 if (endPoint >= 0) { -108 mustContain = i.getValue().substring(19, endPoint).toLowerCase(); -109 break; -110 } -111 } -112 } -113 } -114 if (mustContain != null) { -115 final Iterator<Identifier> itr = dependency.getIdentifiers().iterator(); -116 while (itr.hasNext()) { -117 final Identifier i = itr.next(); -118 if ("cpe".contains(i.getType()) -119 && i.getValue() != null -120 && i.getValue().startsWith("cpe:/a:springsource:") -121 && !i.getValue().toLowerCase().contains(mustContain)) { -122 itr.remove(); -123 //dependency.getIdentifiers().remove(i); -124 } -125 } -126 } -127 } -128 -129 /** -130 * <p> -131 * Intended to remove spurious CPE entries. By spurious we mean duplicate, less specific CPE entries.</p> -132 * <p> -133 * Example:</p> -134 * <code> -135 * cpe:/a:some-vendor:some-product -136 * cpe:/a:some-vendor:some-product:1.5 -137 * cpe:/a:some-vendor:some-product:1.5.2 -138 * </code> -139 * <p> -140 * Should be trimmed to:</p> -141 * <code> -142 * cpe:/a:some-vendor:some-product:1.5.2 -143 * </code> -144 * -145 * @param dependency the dependency being analyzed -146 */ -147 @SuppressWarnings("null") -148 private void removeSpuriousCPE(Dependency dependency) { -149 final List<Identifier> ids = new ArrayList<Identifier>(); -150 ids.addAll(dependency.getIdentifiers()); -151 Collections.sort(ids); -152 final ListIterator<Identifier> mainItr = ids.listIterator(); -153 while (mainItr.hasNext()) { -154 final Identifier currentId = mainItr.next(); -155 final VulnerableSoftware currentCpe = parseCpe(currentId.getType(), currentId.getValue()); -156 if (currentCpe == null) { -157 continue; -158 } -159 final ListIterator<Identifier> subItr = ids.listIterator(mainItr.nextIndex()); -160 while (subItr.hasNext()) { -161 final Identifier nextId = subItr.next(); -162 final VulnerableSoftware nextCpe = parseCpe(nextId.getType(), nextId.getValue()); -163 if (nextCpe == null) { -164 continue; -165 } -166 //TODO fix the version problem below -167 if (currentCpe.getVendor().equals(nextCpe.getVendor())) { -168 if (currentCpe.getProduct().equals(nextCpe.getProduct())) { -169 // see if one is contained in the other.. remove the contained one from dependency.getIdentifier -170 final String currentVersion = currentCpe.getVersion(); -171 final String nextVersion = nextCpe.getVersion(); -172 if (currentVersion == null && nextVersion == null) { -173 //how did we get here? -174 LOGGER.log(Level.FINE, "currentVersion and nextVersion are both null?"); -175 } else if (currentVersion == null && nextVersion != null) { -176 dependency.getIdentifiers().remove(currentId); -177 } else if (nextVersion == null && currentVersion != null) { -178 dependency.getIdentifiers().remove(nextId); -179 } else if (currentVersion.length() < nextVersion.length()) { -180 if (nextVersion.startsWith(currentVersion) || "-".equals(currentVersion)) { -181 dependency.getIdentifiers().remove(currentId); -182 } -183 } else { -184 if (currentVersion.startsWith(nextVersion) || "-".equals(nextVersion)) { -185 dependency.getIdentifiers().remove(nextId); -186 } -187 } -188 } -189 } -190 } -191 } -192 } -193 /** -194 * Regex to identify core java libraries and a few other commonly misidentified ones. -195 */ -196 public static final Pattern CORE_JAVA = Pattern.compile("^cpe:/a:(sun|oracle|ibm):(j2[ems]e|" -197 + "java(_platform_micro_edition|_runtime_environment|_se|virtual_machine|se_development_kit|fx)?|" -198 + "jdk|jre|jsse)($|:.*)"); -199 -200 /** -201 * Regex to identify core jsf libraries. -202 */ -203 public static final Pattern CORE_JAVA_JSF = Pattern.compile("^cpe:/a:(sun|oracle|ibm):jsf($|:.*)"); -204 /** -205 * Regex to identify core java library files. This is currently incomplete. -206 */ -207 public static final Pattern CORE_FILES = Pattern.compile("(^|/)((alt[-])?rt|jsse|jfxrt|jfr|jce|javaws|deploy|charsets)\\.jar$"); +20 import java.io.FileFilter; +21 import java.io.UnsupportedEncodingException; +22 import java.net.URLEncoder; +23 import java.util.ArrayList; +24 import java.util.Collections; +25 import java.util.Iterator; +26 import java.util.List; +27 import java.util.ListIterator; +28 import java.util.Set; +29 import java.util.regex.Matcher; +30 import java.util.regex.Pattern; +31 import org.owasp.dependencycheck.Engine; +32 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; +33 import org.owasp.dependencycheck.dependency.Dependency; +34 import org.owasp.dependencycheck.dependency.Identifier; +35 import org.owasp.dependencycheck.dependency.VulnerableSoftware; +36 import org.owasp.dependencycheck.utils.FileFilterBuilder; +37 import org.slf4j.Logger; +38 import org.slf4j.LoggerFactory; +39 +40 /** +41 * This analyzer attempts to remove some well known false positives - specifically regarding the java runtime. +42 * +43 * @author Jeremy Long +44 */ +45 public class FalsePositiveAnalyzer extends AbstractAnalyzer { +46 +47 /** +48 * The Logger. +49 */ +50 private static final Logger LOGGER = LoggerFactory.getLogger(FalsePositiveAnalyzer.class); +51 +52 /** +53 * The file filter used to find DLL and EXE. +54 */ +55 private static final FileFilter DLL_EXE_FILTER = FileFilterBuilder.newInstance().addExtensions("dll", "exe").build(); +56 +57 //<editor-fold defaultstate="collapsed" desc="All standard implementation details of Analyzer"> +58 /** +59 * The name of the analyzer. +60 */ +61 private static final String ANALYZER_NAME = "False Positive Analyzer"; +62 /** +63 * The phase that this analyzer is intended to run in. +64 */ +65 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.POST_IDENTIFIER_ANALYSIS; +66 +67 /** +68 * Returns the name of the analyzer. +69 * +70 * @return the name of the analyzer. +71 */ +72 public String getName() { +73 return ANALYZER_NAME; +74 } +75 +76 /** +77 * Returns the phase that the analyzer is intended to run in. +78 * +79 * @return the phase that the analyzer is intended to run in. +80 */ +81 public AnalysisPhase getAnalysisPhase() { +82 return ANALYSIS_PHASE; +83 } +84 //</editor-fold> +85 +86 /** +87 * Analyzes the dependencies and removes bad/incorrect CPE associations based on various heuristics. +88 * +89 * @param dependency the dependency to analyze. +90 * @param engine the engine that is scanning the dependencies +91 * @throws AnalysisException is thrown if there is an error reading the JAR file. +92 */ +93 @Override +94 public void analyze(Dependency dependency, Engine engine) throws AnalysisException { +95 removeJreEntries(dependency); +96 removeBadMatches(dependency); +97 removeBadSpringMatches(dependency); +98 removeWrongVersionMatches(dependency); +99 removeSpuriousCPE(dependency); +100 removeDuplicativeEntriesFromJar(dependency, engine); +101 addFalseNegativeCPEs(dependency); +102 } +103 +104 /** +105 * Removes inaccurate matches on springframework CPEs. +106 * +107 * @param dependency the dependency to test for and remove known inaccurate CPE matches +108 */ +109 private void removeBadSpringMatches(Dependency dependency) { +110 String mustContain = null; +111 for (Identifier i : dependency.getIdentifiers()) { +112 if ("maven".contains(i.getType())) { +113 if (i.getValue() != null && i.getValue().startsWith("org.springframework.")) { +114 final int endPoint = i.getValue().indexOf(":", 19); +115 if (endPoint >= 0) { +116 mustContain = i.getValue().substring(19, endPoint).toLowerCase(); +117 break; +118 } +119 } +120 } +121 } +122 if (mustContain != null) { +123 final Iterator<Identifier> itr = dependency.getIdentifiers().iterator(); +124 while (itr.hasNext()) { +125 final Identifier i = itr.next(); +126 if ("cpe".contains(i.getType()) +127 && i.getValue() != null +128 && i.getValue().startsWith("cpe:/a:springsource:") +129 && !i.getValue().toLowerCase().contains(mustContain)) { +130 itr.remove(); +131 //dependency.getIdentifiers().remove(i); +132 } +133 } +134 } +135 } +136 +137 /** +138 * <p> +139 * Intended to remove spurious CPE entries. By spurious we mean duplicate, less specific CPE entries.</p> +140 * <p> +141 * Example:</p> +142 * <code> +143 * cpe:/a:some-vendor:some-product +144 * cpe:/a:some-vendor:some-product:1.5 +145 * cpe:/a:some-vendor:some-product:1.5.2 +146 * </code> +147 * <p> +148 * Should be trimmed to:</p> +149 * <code> +150 * cpe:/a:some-vendor:some-product:1.5.2 +151 * </code> +152 * +153 * @param dependency the dependency being analyzed +154 */ +155 @SuppressWarnings("null") +156 private void removeSpuriousCPE(Dependency dependency) { +157 final List<Identifier> ids = new ArrayList<Identifier>(); +158 ids.addAll(dependency.getIdentifiers()); +159 Collections.sort(ids); +160 final ListIterator<Identifier> mainItr = ids.listIterator(); +161 while (mainItr.hasNext()) { +162 final Identifier currentId = mainItr.next(); +163 final VulnerableSoftware currentCpe = parseCpe(currentId.getType(), currentId.getValue()); +164 if (currentCpe == null) { +165 continue; +166 } +167 final ListIterator<Identifier> subItr = ids.listIterator(mainItr.nextIndex()); +168 while (subItr.hasNext()) { +169 final Identifier nextId = subItr.next(); +170 final VulnerableSoftware nextCpe = parseCpe(nextId.getType(), nextId.getValue()); +171 if (nextCpe == null) { +172 continue; +173 } +174 //TODO fix the version problem below +175 if (currentCpe.getVendor().equals(nextCpe.getVendor())) { +176 if (currentCpe.getProduct().equals(nextCpe.getProduct())) { +177 // see if one is contained in the other.. remove the contained one from dependency.getIdentifier +178 final String currentVersion = currentCpe.getVersion(); +179 final String nextVersion = nextCpe.getVersion(); +180 if (currentVersion == null && nextVersion == null) { +181 //how did we get here? +182 LOGGER.debug("currentVersion and nextVersion are both null?"); +183 } else if (currentVersion == null && nextVersion != null) { +184 dependency.getIdentifiers().remove(currentId); +185 } else if (nextVersion == null && currentVersion != null) { +186 dependency.getIdentifiers().remove(nextId); +187 } else if (currentVersion.length() < nextVersion.length()) { +188 if (nextVersion.startsWith(currentVersion) || "-".equals(currentVersion)) { +189 dependency.getIdentifiers().remove(currentId); +190 } +191 } else { +192 if (currentVersion.startsWith(nextVersion) || "-".equals(nextVersion)) { +193 dependency.getIdentifiers().remove(nextId); +194 } +195 } +196 } +197 } +198 } +199 } +200 } +201 /** +202 * Regex to identify core java libraries and a few other commonly misidentified ones. +203 */ +204 public static final Pattern CORE_JAVA = Pattern.compile("^cpe:/a:(sun|oracle|ibm):(j2[ems]e|" +205 + "java(_platform_micro_edition|_runtime_environment|_se|virtual_machine|se_development_kit|fx)?|" +206 + "jdk|jre|jsse)($|:.*)"); +207 208 /** -209 * Regex to identify core jsf java library files. This is currently incomplete. +209 * Regex to identify core jsf libraries. 210 */ -211 public static final Pattern CORE_JSF_FILES = Pattern.compile("(^|/)jsf[-][^/]*\\.jar$"); -212 -213 /** -214 * Removes any CPE entries for the JDK/JRE unless the filename ends with rt.jar -215 * -216 * @param dependency the dependency to remove JRE CPEs from -217 */ -218 private void removeJreEntries(Dependency dependency) { -219 final Set<Identifier> identifiers = dependency.getIdentifiers(); -220 final Iterator<Identifier> itr = identifiers.iterator(); -221 while (itr.hasNext()) { -222 final Identifier i = itr.next(); -223 final Matcher coreCPE = CORE_JAVA.matcher(i.getValue()); -224 final Matcher coreFiles = CORE_FILES.matcher(dependency.getFileName()); -225 if (coreCPE.matches() && !coreFiles.matches()) { -226 itr.remove(); -227 } -228 final Matcher coreJsfCPE = CORE_JAVA_JSF.matcher(i.getValue()); -229 final Matcher coreJsfFiles = CORE_JSF_FILES.matcher(dependency.getFileName()); -230 if (coreJsfCPE.matches() && !coreJsfFiles.matches()) { -231 itr.remove(); -232 } -233 } -234 } -235 -236 /** -237 * Parses a CPE string into an IndexEntry. -238 * -239 * @param type the type of identifier -240 * @param value the cpe identifier to parse -241 * @return an VulnerableSoftware object constructed from the identifier -242 */ -243 private VulnerableSoftware parseCpe(String type, String value) { -244 if (!"cpe".equals(type)) { -245 return null; -246 } -247 final VulnerableSoftware cpe = new VulnerableSoftware(); -248 try { -249 cpe.parseName(value); -250 } catch (UnsupportedEncodingException ex) { -251 LOGGER.log(Level.FINEST, null, ex); -252 return null; -253 } -254 return cpe; -255 } -256 -257 /** -258 * Removes bad CPE matches for a dependency. Unfortunately, right now these are hard-coded patches for specific -259 * problems identified when testing this on a LARGE volume of jar files. -260 * -261 * @param dependency the dependency to analyze -262 */ -263 private void removeBadMatches(Dependency dependency) { -264 final Set<Identifier> identifiers = dependency.getIdentifiers(); -265 final Iterator<Identifier> itr = identifiers.iterator(); -266 -267 /* TODO - can we utilize the pom's groupid and artifactId to filter??? most of -268 * these are due to low quality data. Other idea would be to say any CPE -269 * found based on LOW confidence evidence should have a different CPE type? (this -270 * might be a better solution then just removing the URL for "best-guess" matches). -271 */ -272 //Set<Evidence> groupId = dependency.getVendorEvidence().getEvidence("pom", "groupid"); -273 //Set<Evidence> artifactId = dependency.getVendorEvidence().getEvidence("pom", "artifactid"); -274 while (itr.hasNext()) { -275 final Identifier i = itr.next(); -276 //TODO move this startsWith expression to a configuration file? -277 if ("cpe".equals(i.getType())) { -278 if ((i.getValue().matches(".*c\\+\\+.*") -279 || i.getValue().startsWith("cpe:/a:file:file") -280 || i.getValue().startsWith("cpe:/a:mozilla:mozilla") -281 || i.getValue().startsWith("cpe:/a:cvs:cvs") -282 || i.getValue().startsWith("cpe:/a:ftp:ftp") -283 || i.getValue().startsWith("cpe:/a:tcp:tcp") -284 || i.getValue().startsWith("cpe:/a:ssh:ssh") -285 || i.getValue().startsWith("cpe:/a:lookup:lookup")) -286 && (dependency.getFileName().toLowerCase().endsWith(".jar") -287 || dependency.getFileName().toLowerCase().endsWith("pom.xml") -288 || dependency.getFileName().toLowerCase().endsWith(".dll") -289 || dependency.getFileName().toLowerCase().endsWith(".exe") -290 || dependency.getFileName().toLowerCase().endsWith(".nuspec") -291 || dependency.getFileName().toLowerCase().endsWith(".nupkg"))) { -292 itr.remove(); -293 } else if ((i.getValue().startsWith("cpe:/a:jquery:jquery") -294 || i.getValue().startsWith("cpe:/a:prototypejs:prototype") -295 || i.getValue().startsWith("cpe:/a:yahoo:yui")) -296 && (dependency.getFileName().toLowerCase().endsWith(".jar") -297 || dependency.getFileName().toLowerCase().endsWith("pom.xml") -298 || dependency.getFileName().toLowerCase().endsWith(".dll") -299 || dependency.getFileName().toLowerCase().endsWith(".exe"))) { -300 itr.remove(); -301 } else if ((i.getValue().startsWith("cpe:/a:microsoft:excel") -302 || i.getValue().startsWith("cpe:/a:microsoft:word") -303 || i.getValue().startsWith("cpe:/a:microsoft:visio") -304 || i.getValue().startsWith("cpe:/a:microsoft:powerpoint") -305 || i.getValue().startsWith("cpe:/a:microsoft:office")) -306 && (dependency.getFileName().toLowerCase().endsWith(".jar") -307 || dependency.getFileName().toLowerCase().endsWith("pom.xml"))) { -308 itr.remove(); -309 } else if (i.getValue().startsWith("cpe:/a:apache:maven") -310 && !dependency.getFileName().toLowerCase().matches("maven-core-[\\d\\.]+\\.jar")) { -311 itr.remove(); -312 } else if (i.getValue().startsWith("cpe:/a:m-core:m-core") -313 && !dependency.getEvidenceUsed().containsUsedString("m-core")) { -314 itr.remove(); -315 } else if (i.getValue().startsWith("cpe:/a:jboss:jboss") -316 && !dependency.getFileName().toLowerCase().matches("jboss-?[\\d\\.-]+(GA)?\\.jar")) { -317 itr.remove(); -318 } -319 } -320 } -321 } -322 -323 /** -324 * Removes CPE matches for the wrong version of a dependency. Currently, this only covers Axis 1 & 2. -325 * -326 * @param dependency the dependency to analyze -327 */ -328 private void removeWrongVersionMatches(Dependency dependency) { -329 final Set<Identifier> identifiers = dependency.getIdentifiers(); -330 final Iterator<Identifier> itr = identifiers.iterator(); -331 -332 final String fileName = dependency.getFileName(); -333 if (fileName != null && fileName.contains("axis2")) { -334 while (itr.hasNext()) { -335 final Identifier i = itr.next(); -336 if ("cpe".equals(i.getType())) { -337 final String cpe = i.getValue(); -338 if (cpe != null && (cpe.startsWith("cpe:/a:apache:axis:") || "cpe:/a:apache:axis".equals(cpe))) { -339 itr.remove(); -340 } -341 } -342 } -343 } else if (fileName != null && fileName.contains("axis")) { -344 while (itr.hasNext()) { -345 final Identifier i = itr.next(); -346 if ("cpe".equals(i.getType())) { -347 final String cpe = i.getValue(); -348 if (cpe != null && (cpe.startsWith("cpe:/a:apache:axis2:") || "cpe:/a:apache:axis2".equals(cpe))) { -349 itr.remove(); -350 } -351 } -352 } -353 } -354 } -355 -356 /** -357 * There are some known CPE entries, specifically regarding sun and oracle products due to the acquisition and -358 * changes in product names, that based on given evidence we can add the related CPE entries to ensure a complete -359 * list of CVE entries. -360 * -361 * @param dependency the dependency being analyzed -362 */ -363 private void addFalseNegativeCPEs(Dependency dependency) { -364 //TODO move this to the hint analyzer -365 final Iterator<Identifier> itr = dependency.getIdentifiers().iterator(); -366 while (itr.hasNext()) { -367 final Identifier i = itr.next(); -368 if ("cpe".equals(i.getType()) && i.getValue() != null -369 && (i.getValue().startsWith("cpe:/a:oracle:opensso:") -370 || i.getValue().startsWith("cpe:/a:oracle:opensso_enterprise:") -371 || i.getValue().startsWith("cpe:/a:sun:opensso_enterprise:") -372 || i.getValue().startsWith("cpe:/a:sun:opensso:"))) { -373 final String newCpe = String.format("cpe:/a:sun:opensso_enterprise:%s", i.getValue().substring(22)); -374 final String newCpe2 = String.format("cpe:/a:oracle:opensso_enterprise:%s", i.getValue().substring(22)); -375 final String newCpe3 = String.format("cpe:/a:sun:opensso:%s", i.getValue().substring(22)); -376 final String newCpe4 = String.format("cpe:/a:oracle:opensso:%s", i.getValue().substring(22)); -377 try { -378 dependency.addIdentifier("cpe", -379 newCpe, -380 String.format(CPEAnalyzer.NVD_SEARCH_URL, URLEncoder.encode(newCpe, "UTF-8"))); -381 dependency.addIdentifier("cpe", -382 newCpe2, -383 String.format(CPEAnalyzer.NVD_SEARCH_URL, URLEncoder.encode(newCpe2, "UTF-8"))); -384 dependency.addIdentifier("cpe", -385 newCpe3, -386 String.format(CPEAnalyzer.NVD_SEARCH_URL, URLEncoder.encode(newCpe3, "UTF-8"))); -387 dependency.addIdentifier("cpe", -388 newCpe4, -389 String.format(CPEAnalyzer.NVD_SEARCH_URL, URLEncoder.encode(newCpe4, "UTF-8"))); -390 } catch (UnsupportedEncodingException ex) { -391 LOGGER.log(Level.FINE, null, ex); -392 } -393 } -394 } -395 } -396 -397 /** -398 * Removes duplicate entries identified that are contained within JAR files. These occasionally crop up due to POM -399 * entries or other types of files (such as DLLs and EXEs) being contained within the JAR. -400 * -401 * @param dependency the dependency that might be a duplicate -402 * @param engine the engine used to scan all dependencies -403 */ -404 private void removeDuplicativeEntriesFromJar(Dependency dependency, Engine engine) { -405 if (dependency.getFileName().toLowerCase().endsWith("pom.xml") -406 || "dll".equals(dependency.getFileExtension()) -407 || "exe".equals(dependency.getFileExtension())) { -408 String parentPath = dependency.getFilePath().toLowerCase(); -409 if (parentPath.contains(".jar")) { -410 parentPath = parentPath.substring(0, parentPath.indexOf(".jar") + 4); -411 final Dependency parent = findDependency(parentPath, engine.getDependencies()); -412 if (parent != null) { -413 boolean remove = false; -414 for (Identifier i : dependency.getIdentifiers()) { -415 if ("cpe".equals(i.getType())) { -416 final String trimmedCPE = trimCpeToVendor(i.getValue()); -417 for (Identifier parentId : parent.getIdentifiers()) { -418 if ("cpe".equals(parentId.getType()) && parentId.getValue().startsWith(trimmedCPE)) { -419 remove |= true; -420 } -421 } -422 } -423 if (!remove) { //we can escape early -424 return; -425 } -426 } -427 if (remove) { -428 engine.getDependencies().remove(dependency); -429 } -430 } -431 } -432 -433 } -434 } -435 -436 /** -437 * Retrieves a given dependency, based on a given path, from a list of dependencies. -438 * -439 * @param dependencyPath the path of the dependency to return -440 * @param dependencies the collection of dependencies to search -441 * @return the dependency object for the given path, otherwise null -442 */ -443 private Dependency findDependency(String dependencyPath, List<Dependency> dependencies) { -444 for (Dependency d : dependencies) { -445 if (d.getFilePath().equalsIgnoreCase(dependencyPath)) { -446 return d; +211 public static final Pattern CORE_JAVA_JSF = Pattern.compile("^cpe:/a:(sun|oracle|ibm):jsf($|:.*)"); +212 /** +213 * Regex to identify core java library files. This is currently incomplete. +214 */ +215 public static final Pattern CORE_FILES = Pattern.compile("(^|/)((alt[-])?rt|jsse|jfxrt|jfr|jce|javaws|deploy|charsets)\\.jar$"); +216 /** +217 * Regex to identify core jsf java library files. This is currently incomplete. +218 */ +219 public static final Pattern CORE_JSF_FILES = Pattern.compile("(^|/)jsf[-][^/]*\\.jar$"); +220 +221 /** +222 * Removes any CPE entries for the JDK/JRE unless the filename ends with rt.jar +223 * +224 * @param dependency the dependency to remove JRE CPEs from +225 */ +226 private void removeJreEntries(Dependency dependency) { +227 final Set<Identifier> identifiers = dependency.getIdentifiers(); +228 final Iterator<Identifier> itr = identifiers.iterator(); +229 while (itr.hasNext()) { +230 final Identifier i = itr.next(); +231 final Matcher coreCPE = CORE_JAVA.matcher(i.getValue()); +232 final Matcher coreFiles = CORE_FILES.matcher(dependency.getFileName()); +233 if (coreCPE.matches() && !coreFiles.matches()) { +234 itr.remove(); +235 } +236 final Matcher coreJsfCPE = CORE_JAVA_JSF.matcher(i.getValue()); +237 final Matcher coreJsfFiles = CORE_JSF_FILES.matcher(dependency.getFileName()); +238 if (coreJsfCPE.matches() && !coreJsfFiles.matches()) { +239 itr.remove(); +240 } +241 } +242 } +243 +244 /** +245 * Parses a CPE string into an IndexEntry. +246 * +247 * @param type the type of identifier +248 * @param value the cpe identifier to parse +249 * @return an VulnerableSoftware object constructed from the identifier +250 */ +251 private VulnerableSoftware parseCpe(String type, String value) { +252 if (!"cpe".equals(type)) { +253 return null; +254 } +255 final VulnerableSoftware cpe = new VulnerableSoftware(); +256 try { +257 cpe.parseName(value); +258 } catch (UnsupportedEncodingException ex) { +259 LOGGER.trace("", ex); +260 return null; +261 } +262 return cpe; +263 } +264 +265 /** +266 * Removes bad CPE matches for a dependency. Unfortunately, right now these are hard-coded patches for specific problems +267 * identified when testing this on a LARGE volume of jar files. +268 * +269 * @param dependency the dependency to analyze +270 */ +271 private void removeBadMatches(Dependency dependency) { +272 final Set<Identifier> identifiers = dependency.getIdentifiers(); +273 final Iterator<Identifier> itr = identifiers.iterator(); +274 +275 /* TODO - can we utilize the pom's groupid and artifactId to filter??? most of +276 * these are due to low quality data. Other idea would be to say any CPE +277 * found based on LOW confidence evidence should have a different CPE type? (this +278 * might be a better solution then just removing the URL for "best-guess" matches). +279 */ +280 //Set<Evidence> groupId = dependency.getVendorEvidence().getEvidence("pom", "groupid"); +281 //Set<Evidence> artifactId = dependency.getVendorEvidence().getEvidence("pom", "artifactid"); +282 while (itr.hasNext()) { +283 final Identifier i = itr.next(); +284 //TODO move this startsWith expression to the base suppression file +285 if ("cpe".equals(i.getType())) { +286 if ((i.getValue().matches(".*c\\+\\+.*") +287 || i.getValue().startsWith("cpe:/a:file:file") +288 || i.getValue().startsWith("cpe:/a:mozilla:mozilla") +289 || i.getValue().startsWith("cpe:/a:cvs:cvs") +290 || i.getValue().startsWith("cpe:/a:ftp:ftp") +291 || i.getValue().startsWith("cpe:/a:tcp:tcp") +292 || i.getValue().startsWith("cpe:/a:ssh:ssh") +293 || i.getValue().startsWith("cpe:/a:lookup:lookup")) +294 && (dependency.getFileName().toLowerCase().endsWith(".jar") +295 || dependency.getFileName().toLowerCase().endsWith("pom.xml") +296 || dependency.getFileName().toLowerCase().endsWith(".dll") +297 || dependency.getFileName().toLowerCase().endsWith(".exe") +298 || dependency.getFileName().toLowerCase().endsWith(".nuspec") +299 || dependency.getFileName().toLowerCase().endsWith(".zip") +300 || dependency.getFileName().toLowerCase().endsWith(".sar") +301 || dependency.getFileName().toLowerCase().endsWith(".apk") +302 || dependency.getFileName().toLowerCase().endsWith(".tar") +303 || dependency.getFileName().toLowerCase().endsWith(".gz") +304 || dependency.getFileName().toLowerCase().endsWith(".tgz") +305 || dependency.getFileName().toLowerCase().endsWith(".ear") +306 || dependency.getFileName().toLowerCase().endsWith(".war"))) { +307 itr.remove(); +308 } else if ((i.getValue().startsWith("cpe:/a:jquery:jquery") +309 || i.getValue().startsWith("cpe:/a:prototypejs:prototype") +310 || i.getValue().startsWith("cpe:/a:yahoo:yui")) +311 && (dependency.getFileName().toLowerCase().endsWith(".jar") +312 || dependency.getFileName().toLowerCase().endsWith("pom.xml") +313 || dependency.getFileName().toLowerCase().endsWith(".dll") +314 || dependency.getFileName().toLowerCase().endsWith(".exe"))) { +315 itr.remove(); +316 } else if ((i.getValue().startsWith("cpe:/a:microsoft:excel") +317 || i.getValue().startsWith("cpe:/a:microsoft:word") +318 || i.getValue().startsWith("cpe:/a:microsoft:visio") +319 || i.getValue().startsWith("cpe:/a:microsoft:powerpoint") +320 || i.getValue().startsWith("cpe:/a:microsoft:office") +321 || i.getValue().startsWith("cpe:/a:core_ftp:core_ftp")) +322 && (dependency.getFileName().toLowerCase().endsWith(".jar") +323 || dependency.getFileName().toLowerCase().endsWith(".ear") +324 || dependency.getFileName().toLowerCase().endsWith(".war") +325 || dependency.getFileName().toLowerCase().endsWith("pom.xml"))) { +326 itr.remove(); +327 } else if (i.getValue().startsWith("cpe:/a:apache:maven") +328 && !dependency.getFileName().toLowerCase().matches("maven-core-[\\d\\.]+\\.jar")) { +329 itr.remove(); +330 } else if (i.getValue().startsWith("cpe:/a:m-core:m-core") +331 && !dependency.getEvidenceUsed().containsUsedString("m-core")) { +332 itr.remove(); +333 } else if (i.getValue().startsWith("cpe:/a:jboss:jboss") +334 && !dependency.getFileName().toLowerCase().matches("jboss-?[\\d\\.-]+(GA)?\\.jar")) { +335 itr.remove(); +336 } +337 } +338 } +339 } +340 +341 /** +342 * Removes CPE matches for the wrong version of a dependency. Currently, this only covers Axis 1 & 2. +343 * +344 * @param dependency the dependency to analyze +345 */ +346 private void removeWrongVersionMatches(Dependency dependency) { +347 final Set<Identifier> identifiers = dependency.getIdentifiers(); +348 final Iterator<Identifier> itr = identifiers.iterator(); +349 +350 final String fileName = dependency.getFileName(); +351 if (fileName != null && fileName.contains("axis2")) { +352 while (itr.hasNext()) { +353 final Identifier i = itr.next(); +354 if ("cpe".equals(i.getType())) { +355 final String cpe = i.getValue(); +356 if (cpe != null && (cpe.startsWith("cpe:/a:apache:axis:") || "cpe:/a:apache:axis".equals(cpe))) { +357 itr.remove(); +358 } +359 } +360 } +361 } else if (fileName != null && fileName.contains("axis")) { +362 while (itr.hasNext()) { +363 final Identifier i = itr.next(); +364 if ("cpe".equals(i.getType())) { +365 final String cpe = i.getValue(); +366 if (cpe != null && (cpe.startsWith("cpe:/a:apache:axis2:") || "cpe:/a:apache:axis2".equals(cpe))) { +367 itr.remove(); +368 } +369 } +370 } +371 } +372 } +373 +374 /** +375 * There are some known CPE entries, specifically regarding sun and oracle products due to the acquisition and changes in +376 * product names, that based on given evidence we can add the related CPE entries to ensure a complete list of CVE entries. +377 * +378 * @param dependency the dependency being analyzed +379 */ +380 private void addFalseNegativeCPEs(Dependency dependency) { +381 //TODO move this to the hint analyzer +382 final Iterator<Identifier> itr = dependency.getIdentifiers().iterator(); +383 while (itr.hasNext()) { +384 final Identifier i = itr.next(); +385 if ("cpe".equals(i.getType()) && i.getValue() != null +386 && (i.getValue().startsWith("cpe:/a:oracle:opensso:") +387 || i.getValue().startsWith("cpe:/a:oracle:opensso_enterprise:") +388 || i.getValue().startsWith("cpe:/a:sun:opensso_enterprise:") +389 || i.getValue().startsWith("cpe:/a:sun:opensso:"))) { +390 final String newCpe = String.format("cpe:/a:sun:opensso_enterprise:%s", i.getValue().substring(22)); +391 final String newCpe2 = String.format("cpe:/a:oracle:opensso_enterprise:%s", i.getValue().substring(22)); +392 final String newCpe3 = String.format("cpe:/a:sun:opensso:%s", i.getValue().substring(22)); +393 final String newCpe4 = String.format("cpe:/a:oracle:opensso:%s", i.getValue().substring(22)); +394 try { +395 dependency.addIdentifier("cpe", +396 newCpe, +397 String.format(CPEAnalyzer.NVD_SEARCH_URL, URLEncoder.encode(newCpe, "UTF-8"))); +398 dependency.addIdentifier("cpe", +399 newCpe2, +400 String.format(CPEAnalyzer.NVD_SEARCH_URL, URLEncoder.encode(newCpe2, "UTF-8"))); +401 dependency.addIdentifier("cpe", +402 newCpe3, +403 String.format(CPEAnalyzer.NVD_SEARCH_URL, URLEncoder.encode(newCpe3, "UTF-8"))); +404 dependency.addIdentifier("cpe", +405 newCpe4, +406 String.format(CPEAnalyzer.NVD_SEARCH_URL, URLEncoder.encode(newCpe4, "UTF-8"))); +407 } catch (UnsupportedEncodingException ex) { +408 LOGGER.debug("", ex); +409 } +410 } +411 } +412 } +413 +414 /** +415 * Removes duplicate entries identified that are contained within JAR files. These occasionally crop up due to POM entries or +416 * other types of files (such as DLLs and EXEs) being contained within the JAR. +417 * +418 * @param dependency the dependency that might be a duplicate +419 * @param engine the engine used to scan all dependencies +420 */ +421 private void removeDuplicativeEntriesFromJar(Dependency dependency, Engine engine) { +422 if (dependency.getFileName().toLowerCase().endsWith("pom.xml") +423 || DLL_EXE_FILTER.accept(dependency.getActualFile())) { +424 String parentPath = dependency.getFilePath().toLowerCase(); +425 if (parentPath.contains(".jar")) { +426 parentPath = parentPath.substring(0, parentPath.indexOf(".jar") + 4); +427 final Dependency parent = findDependency(parentPath, engine.getDependencies()); +428 if (parent != null) { +429 boolean remove = false; +430 for (Identifier i : dependency.getIdentifiers()) { +431 if ("cpe".equals(i.getType())) { +432 final String trimmedCPE = trimCpeToVendor(i.getValue()); +433 for (Identifier parentId : parent.getIdentifiers()) { +434 if ("cpe".equals(parentId.getType()) && parentId.getValue().startsWith(trimmedCPE)) { +435 remove |= true; +436 } +437 } +438 } +439 if (!remove) { //we can escape early +440 return; +441 } +442 } +443 if (remove) { +444 engine.getDependencies().remove(dependency); +445 } +446 } 447 } -448 } -449 return null; +448 +449 } 450 } 451 452 /** -453 * Takes a full CPE and returns the CPE trimmed to include only vendor and product. +453 * Retrieves a given dependency, based on a given path, from a list of dependencies. 454 * -455 * @param value the CPE value to trim -456 * @return a CPE value that only includes the vendor and product -457 */ -458 private String trimCpeToVendor(String value) { -459 //cpe:/a:jruby:jruby:1.0.8 -460 final int pos1 = value.indexOf(":", 7); //right of vendor -461 final int pos2 = value.indexOf(":", pos1 + 1); //right of product -462 if (pos2 < 0) { -463 return value; -464 } else { -465 return value.substring(0, pos2); -466 } -467 } -468 } +455 * @param dependencyPath the path of the dependency to return +456 * @param dependencies the collection of dependencies to search +457 * @return the dependency object for the given path, otherwise null +458 */ +459 private Dependency findDependency(String dependencyPath, List<Dependency> dependencies) { +460 for (Dependency d : dependencies) { +461 if (d.getFilePath().equalsIgnoreCase(dependencyPath)) { +462 return d; +463 } +464 } +465 return null; +466 } +467 +468 /** +469 * Takes a full CPE and returns the CPE trimmed to include only vendor and product. +470 * +471 * @param value the CPE value to trim +472 * @return a CPE value that only includes the vendor and product +473 */ +474 private String trimCpeToVendor(String value) { +475 //cpe:/a:jruby:jruby:1.0.8 +476 final int pos1 = value.indexOf(":", 7); //right of vendor +477 final int pos2 = value.indexOf(":", pos1 + 1); //right of product +478 if (pos2 < 0) { +479 return value; +480 } else { +481 return value.substring(0, pos2); +482 } +483 } +484 }
    diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/FileTypeAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/FileTypeAnalyzer.html index d4f64f86e..f4a037714 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/FileTypeAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/FileTypeAnalyzer.html @@ -25,26 +25,20 @@ 17 */ 18 package org.owasp.dependencycheck.analyzer; 19 -20 /** -21 * An Analyzer that scans specific file types. -22 * -23 * @author Jeremy Long -24 */ -25 public interface FileTypeAnalyzer extends Analyzer { -26 -27 /** -28 * Returns whether or not this analyzer can process the given extension. -29 * -30 * @param extension the file extension to test for support. -31 * @return whether or not the specified file extension is supported by this analyzer. -32 */ -33 boolean supportsExtension(String extension); -34 -35 /** -36 * Resets the analyzers state. -37 */ -38 void reset(); -39 } +20 import java.io.FileFilter; +21 +22 /** +23 * An Analyzer that scans specific file types. +24 * +25 * @author Jeremy Long +26 */ +27 public interface FileTypeAnalyzer extends Analyzer, FileFilter { +28 +29 /** +30 * Resets the analyzers state. +31 */ +32 void reset(); +33 }
    diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/HintAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/HintAnalyzer.html index 272810d1d..e033d284a 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/HintAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/HintAnalyzer.html @@ -97,51 +97,64 @@ 89 "spring-core", 90 Confidence.HIGH); 91 -92 final Evidence springTest4 = new Evidence("Manifest", -93 "Bundle-Vendor", -94 "SpringSource", -95 Confidence.HIGH); +92 final Evidence springTest4 = new Evidence("jar", +93 "package name", +94 "springframework", +95 Confidence.LOW); 96 -97 final Evidence springTest5 = new Evidence("jar", -98 "package name", -99 "springframework", -100 Confidence.LOW); +97 final Evidence springSecurityTest1 = new Evidence("Manifest", +98 "Bundle-Name", +99 "Spring Security Core", +100 Confidence.MEDIUM); 101 -102 //springsource/vware problem -103 final Set<Evidence> product = dependency.getProductEvidence().getEvidence(); -104 final Set<Evidence> vendor = dependency.getVendorEvidence().getEvidence(); -105 -106 if (product.contains(springTest1) || product.contains(springTest2) || product.contains(springTest3) -107 || (dependency.getFileName().contains("spring") && (product.contains(springTest5) || vendor.contains(springTest5)))) { -108 dependency.getProductEvidence().addEvidence("hint analyzer", "product", "springsource spring framework", Confidence.HIGH); -109 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "SpringSource", Confidence.HIGH); -110 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "vmware", Confidence.HIGH); -111 } -112 -113 if (vendor.contains(springTest4)) { -114 dependency.getProductEvidence().addEvidence("hint analyzer", "product", "springsource_spring_framework", Confidence.HIGH); +102 final Evidence springSecurityTest2 = new Evidence("pom", +103 "artifactid", +104 "spring-security-core", +105 Confidence.HIGH); +106 +107 //springsource/vware problem +108 final Set<Evidence> product = dependency.getProductEvidence().getEvidence(); +109 final Set<Evidence> vendor = dependency.getVendorEvidence().getEvidence(); +110 +111 if (product.contains(springTest1) || product.contains(springTest2) || product.contains(springTest3) +112 || (dependency.getFileName().contains("spring") && product.contains(springTest4))) { +113 dependency.getProductEvidence().addEvidence("hint analyzer", "product", "springsource spring framework", Confidence.HIGH); +114 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "SpringSource", Confidence.HIGH); 115 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "vmware", Confidence.HIGH); -116 } -117 -118 //sun/oracle problem -119 final Iterator<Evidence> itr = dependency.getVendorEvidence().iterator(); -120 final List<Evidence> newEntries = new ArrayList<Evidence>(); -121 while (itr.hasNext()) { -122 final Evidence e = itr.next(); -123 if ("sun".equalsIgnoreCase(e.getValue(false))) { -124 final Evidence newEvidence = new Evidence(e.getSource() + " (hint)", e.getName(), "oracle", e.getConfidence()); -125 newEntries.add(newEvidence); -126 } else if ("oracle".equalsIgnoreCase(e.getValue(false))) { -127 final Evidence newEvidence = new Evidence(e.getSource() + " (hint)", e.getName(), "sun", e.getConfidence()); -128 newEntries.add(newEvidence); -129 } -130 } -131 for (Evidence e : newEntries) { -132 dependency.getVendorEvidence().addEvidence(e); -133 } -134 -135 } -136 } +116 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "pivotal", Confidence.HIGH); +117 } +118 +119 if (vendor.contains(springTest4)) { +120 dependency.getProductEvidence().addEvidence("hint analyzer", "product", "springsource_spring_framework", Confidence.HIGH); +121 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "vmware", Confidence.HIGH); +122 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "pivotal", Confidence.HIGH); +123 } +124 +125 if (product.contains(springSecurityTest1) || product.contains(springSecurityTest2)) { +126 dependency.getProductEvidence().addEvidence("hint analyzer", "product", "springsource_spring_security", Confidence.HIGH); +127 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "SpringSource", Confidence.HIGH); +128 dependency.getVendorEvidence().addEvidence("hint analyzer", "vendor", "vmware", Confidence.HIGH); +129 } +130 +131 //sun/oracle problem +132 final Iterator<Evidence> itr = dependency.getVendorEvidence().iterator(); +133 final List<Evidence> newEntries = new ArrayList<Evidence>(); +134 while (itr.hasNext()) { +135 final Evidence e = itr.next(); +136 if ("sun".equalsIgnoreCase(e.getValue(false))) { +137 final Evidence newEvidence = new Evidence(e.getSource() + " (hint)", e.getName(), "oracle", e.getConfidence()); +138 newEntries.add(newEvidence); +139 } else if ("oracle".equalsIgnoreCase(e.getValue(false))) { +140 final Evidence newEvidence = new Evidence(e.getSource() + " (hint)", e.getName(), "sun", e.getConfidence()); +141 newEntries.add(newEvidence); +142 } +143 } +144 for (Evidence e : newEntries) { +145 dependency.getVendorEvidence().addEvidence(e); +146 } +147 +148 } +149 }
    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 ff6a9d296..0eebc2360 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/JarAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/JarAnalyzer.html @@ -27,1164 +27,1176 @@ 19 20 import java.io.BufferedOutputStream; 21 import java.io.File; -22 import java.io.FileOutputStream; -23 import java.io.IOException; -24 import java.io.InputStream; -25 import java.io.InputStreamReader; -26 import java.io.OutputStream; -27 import java.io.Reader; -28 import java.util.ArrayList; -29 import java.util.Collections; -30 import java.util.Enumeration; -31 import java.util.HashMap; -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.logging.Level; -43 import java.util.logging.Logger; -44 import java.util.regex.Pattern; -45 import java.util.zip.ZipEntry; -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; +22 import java.io.FileFilter; +23 import java.io.FileOutputStream; +24 import java.io.IOException; +25 import java.io.InputStream; +26 import java.io.InputStreamReader; +27 import java.io.OutputStream; +28 import java.io.Reader; +29 import java.util.ArrayList; +30 import java.util.Collections; +31 import java.util.Enumeration; +32 import java.util.HashMap; +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.jsoup.Jsoup; +46 import org.owasp.dependencycheck.Engine; +47 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; +48 import org.owasp.dependencycheck.dependency.Confidence; +49 import org.owasp.dependencycheck.dependency.Dependency; +50 import org.owasp.dependencycheck.dependency.EvidenceCollection; +51 import org.owasp.dependencycheck.utils.FileFilterBuilder; 52 import org.owasp.dependencycheck.xml.pom.License; 53 import org.owasp.dependencycheck.xml.pom.PomUtils; 54 import org.owasp.dependencycheck.xml.pom.Model; 55 import org.owasp.dependencycheck.utils.FileUtils; 56 import org.owasp.dependencycheck.utils.Settings; -57 -58 /** -59 * Used to load a JAR file and collect information that can be used to determine the associated CPE. -60 * -61 * @author Jeremy Long -62 */ -63 public class JarAnalyzer extends AbstractFileTypeAnalyzer { -64 -65 //<editor-fold defaultstate="collapsed" desc="Constants and Member Variables"> -66 /** -67 * The logger. -68 */ -69 private static final Logger LOGGER = Logger.getLogger(JarAnalyzer.class.getName()); -70 /** -71 * The buffer size to use when extracting files from the archive. -72 */ -73 private static final int BUFFER_SIZE = 4096; -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 "include-resource", -120 "embed-dependency", -121 "ipojo-components", -122 "ipojo-extension", -123 "eclipse-sourcereferences"); -124 /** -125 * item in some manifest, should be considered medium confidence. -126 */ -127 private static final String BUNDLE_VERSION = "Bundle-Version"; //: 2.1.2 -128 /** -129 * item in some manifest, should be considered medium confidence. -130 */ -131 private static final String BUNDLE_DESCRIPTION = "Bundle-Description"; //: Apache Struts 2 -132 /** -133 * item in some manifest, should be considered medium confidence. -134 */ -135 private static final String BUNDLE_NAME = "Bundle-Name"; //: Struts 2 Core -136 /** -137 * item in some manifest, should be considered medium confidence. -138 */ -139 private static final String BUNDLE_VENDOR = "Bundle-Vendor"; //: Apache Software Foundation -140 /** -141 * A pattern to detect HTML within text. -142 */ -143 private static final Pattern HTML_DETECTION_PATTERN = Pattern.compile("\\<[a-z]+.*/?\\>", Pattern.CASE_INSENSITIVE); -144 -145 //</editor-fold> -146 /** -147 * Constructs a new JarAnalyzer. -148 */ -149 public JarAnalyzer() { -150 } -151 -152 //<editor-fold defaultstate="collapsed" desc="All standard implmentation details of Analyzer"> -153 /** -154 * The name of the analyzer. -155 */ -156 private static final String ANALYZER_NAME = "Jar Analyzer"; -157 /** -158 * The phase that this analyzer is intended to run in. -159 */ -160 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; -161 /** -162 * The set of file extensions supported by this analyzer. -163 */ -164 private static final Set<String> EXTENSIONS = newHashSet("jar", "war"); -165 +57 import org.slf4j.Logger; +58 import org.slf4j.LoggerFactory; +59 +60 /** +61 * Used to load a JAR file and collect information that can be used to determine the associated CPE. +62 * +63 * @author Jeremy Long +64 */ +65 public class JarAnalyzer extends AbstractFileTypeAnalyzer { +66 +67 //<editor-fold defaultstate="collapsed" desc="Constants and Member Variables"> +68 /** +69 * The logger. +70 */ +71 private static final Logger LOGGER = LoggerFactory.getLogger(JarAnalyzer.class); +72 /** +73 * The buffer size to use when extracting files from the archive. +74 */ +75 private static final int BUFFER_SIZE = 4096; +76 /** +77 * The count of directories created during analysis. This is used for creating temporary directories. +78 */ +79 private static int dirCount = 0; +80 /** +81 * The system independent newline character. +82 */ +83 private static final String NEWLINE = System.getProperty("line.separator"); +84 /** +85 * A list of values in the manifest to ignore as they only result in false 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 analysis. +129 */ +130 @SuppressWarnings("deprecation") +131 private static final String IMPLEMENTATION_VENDOR_ID = Attributes.Name.IMPLEMENTATION_VENDOR_ID +132 .toString(); +133 /** +134 * item in some manifest, should be considered medium confidence. +135 */ +136 private static final String BUNDLE_VERSION = "Bundle-Version"; //: 2.1.2 +137 /** +138 * item in some manifest, should be considered medium confidence. +139 */ +140 private static final String BUNDLE_DESCRIPTION = "Bundle-Description"; //: Apache Struts 2 +141 /** +142 * item in some manifest, should be considered medium confidence. +143 */ +144 private static final String BUNDLE_NAME = "Bundle-Name"; //: Struts 2 Core +145 /** +146 * A pattern to detect HTML within text. +147 */ +148 private static final Pattern HTML_DETECTION_PATTERN = Pattern.compile("\\<[a-z]+.*/?\\>", Pattern.CASE_INSENSITIVE); +149 +150 //</editor-fold> +151 /** +152 * Constructs a new JarAnalyzer. +153 */ +154 public JarAnalyzer() { +155 } +156 +157 //<editor-fold defaultstate="collapsed" desc="All standard implmentation details of Analyzer"> +158 /** +159 * The name of the analyzer. +160 */ +161 private static final String ANALYZER_NAME = "Jar Analyzer"; +162 /** +163 * The phase that this analyzer is intended to run in. +164 */ +165 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; 166 /** -167 * Returns a list of file EXTENSIONS supported by this analyzer. -168 * -169 * @return a list of file EXTENSIONS supported by this analyzer. -170 */ -171 @Override -172 public Set<String> getSupportedExtensions() { -173 return EXTENSIONS; -174 } +167 * The set of file extensions supported by this analyzer. +168 */ +169 private static final String[] EXTENSIONS = {"jar", "war"}; +170 +171 /** +172 * The file filter used to determine which files this analyzer supports. +173 */ +174 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(EXTENSIONS).build(); 175 176 /** -177 * Returns the name of the analyzer. +177 * Returns the FileFilter. 178 * -179 * @return the name of the analyzer. +179 * @return the FileFilter 180 */ 181 @Override -182 public String getName() { -183 return ANALYZER_NAME; +182 protected FileFilter getFileFilter() { +183 return FILTER; 184 } 185 186 /** -187 * Returns the phase that the analyzer is intended to run in. +187 * Returns the name of the analyzer. 188 * -189 * @return the phase that the analyzer is intended to run in. +189 * @return the name of the analyzer. 190 */ -191 public AnalysisPhase getAnalysisPhase() { -192 return ANALYSIS_PHASE; -193 } -194 //</editor-fold> +191 @Override +192 public String getName() { +193 return ANALYZER_NAME; +194 } 195 196 /** -197 * Returns the key used in the properties file to reference the analyzer's enabled property. +197 * Returns the phase that the analyzer is intended to run in. 198 * -199 * @return the analyzer's enabled property setting key +199 * @return the phase that the analyzer is intended to run in. 200 */ -201 @Override -202 protected String getAnalyzerEnabledSettingKey() { -203 return Settings.KEYS.ANALYZER_JAR_ENABLED; -204 } +201 public AnalysisPhase getAnalysisPhase() { +202 return ANALYSIS_PHASE; +203 } +204 //</editor-fold> 205 206 /** -207 * Loads a specified JAR file and collects information from the manifest and checksums to identify the correct CPE -208 * information. -209 * -210 * @param dependency the dependency to analyze. -211 * @param engine the engine that is scanning the dependencies -212 * @throws AnalysisException is thrown if there is an error reading the JAR file. -213 */ -214 @Override -215 public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { -216 try { -217 final List<ClassNameInformation> classNames = collectClassNames(dependency); -218 final String fileName = dependency.getFileName().toLowerCase(); -219 if (classNames.isEmpty() -220 && (fileName.endsWith("-sources.jar") -221 || fileName.endsWith("-javadoc.jar") -222 || fileName.endsWith("-src.jar") -223 || fileName.endsWith("-doc.jar"))) { -224 engine.getDependencies().remove(dependency); -225 } -226 final boolean hasManifest = parseManifest(dependency, classNames); -227 final boolean hasPOM = analyzePOM(dependency, classNames, engine); -228 final boolean addPackagesAsEvidence = !(hasManifest && hasPOM); -229 analyzePackageNames(classNames, dependency, addPackagesAsEvidence); -230 } catch (IOException ex) { -231 throw new AnalysisException("Exception occurred reading the JAR file.", ex); -232 } -233 } -234 -235 /** -236 * Attempts to find a pom.xml within the JAR file. If found it extracts information and adds it to the evidence. This will -237 * attempt to interpolate the strings contained within the pom.properties if one exists. -238 * -239 * @param dependency the dependency being analyzed -240 * @param classes a collection of class name information -241 * @param engine the analysis engine, used to add additional dependencies -242 * @throws AnalysisException is thrown if there is an exception parsing the pom -243 * @return whether or not evidence was added to the dependency -244 */ -245 protected boolean analyzePOM(Dependency dependency, List<ClassNameInformation> classes, Engine engine) throws AnalysisException { -246 boolean foundSomething = false; -247 final JarFile jar; -248 try { -249 jar = new JarFile(dependency.getActualFilePath()); -250 } catch (IOException ex) { -251 final String msg = String.format("Unable to read JarFile '%s'.", dependency.getActualFilePath()); -252 //final AnalysisException ax = new AnalysisException(msg, ex); -253 LOGGER.log(Level.WARNING, msg); -254 LOGGER.log(Level.FINE, "", ex); -255 return false; -256 } -257 List<String> pomEntries; +207 * Returns the key used in the properties file to reference the analyzer's enabled property. +208 * +209 * @return the analyzer's enabled property setting key +210 */ +211 @Override +212 protected String getAnalyzerEnabledSettingKey() { +213 return Settings.KEYS.ANALYZER_JAR_ENABLED; +214 } +215 +216 /** +217 * Loads a specified JAR file and collects information from the manifest and checksums to identify the correct CPE +218 * information. +219 * +220 * @param dependency the dependency to analyze. +221 * @param engine the engine that is scanning the dependencies +222 * @throws AnalysisException is thrown if there is an error reading the JAR file. +223 */ +224 @Override +225 public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { +226 try { +227 final List<ClassNameInformation> classNames = collectClassNames(dependency); +228 final String fileName = dependency.getFileName().toLowerCase(); +229 if (classNames.isEmpty() +230 && (fileName.endsWith("-sources.jar") +231 || fileName.endsWith("-javadoc.jar") +232 || fileName.endsWith("-src.jar") +233 || fileName.endsWith("-doc.jar"))) { +234 engine.getDependencies().remove(dependency); +235 } +236 final boolean hasManifest = parseManifest(dependency, classNames); +237 final boolean hasPOM = analyzePOM(dependency, classNames, engine); +238 final boolean addPackagesAsEvidence = !(hasManifest && hasPOM); +239 analyzePackageNames(classNames, dependency, addPackagesAsEvidence); +240 } catch (IOException ex) { +241 throw new AnalysisException("Exception occurred reading the JAR file.", ex); +242 } +243 } +244 +245 /** +246 * Attempts to find a pom.xml within the JAR file. If found it extracts information and adds it to the evidence. This will +247 * attempt to interpolate the strings contained within the pom.properties if one exists. +248 * +249 * @param dependency the dependency being analyzed +250 * @param classes a collection of class name information +251 * @param engine the analysis engine, used to add additional dependencies +252 * @throws AnalysisException is thrown if there is an exception parsing the pom +253 * @return whether or not evidence was added to the dependency +254 */ +255 protected boolean analyzePOM(Dependency dependency, List<ClassNameInformation> classes, Engine engine) throws AnalysisException { +256 boolean foundSomething = false; +257 final JarFile jar; 258 try { -259 pomEntries = retrievePomListing(jar); +259 jar = new JarFile(dependency.getActualFilePath()); 260 } catch (IOException ex) { -261 final String msg = String.format("Unable to read Jar file entries in '%s'.", dependency.getActualFilePath()); -262 //final AnalysisException ax = new AnalysisException(msg, ex); -263 LOGGER.log(Level.WARNING, msg); -264 LOGGER.log(Level.FINE, msg, ex); -265 return false; -266 } -267 File externalPom = null; -268 if (pomEntries.isEmpty()) { -269 String pomPath = dependency.getActualFilePath(); -270 pomPath = pomPath.substring(0, pomPath.lastIndexOf('.')) + ".pom"; -271 externalPom = new File(pomPath); -272 if (externalPom.isFile()) { -273 pomEntries.add(pomPath); -274 } else { -275 return false; -276 } -277 } -278 for (String path : pomEntries) { -279 LOGGER.fine(String.format("Reading pom entry: %s", path)); -280 Properties pomProperties = null; -281 try { -282 if (externalPom == null) { -283 pomProperties = retrievePomProperties(path, jar); -284 } -285 } catch (IOException ex) { -286 LOGGER.log(Level.FINEST, "ignore this, failed reading a non-existent pom.properties", ex); -287 } -288 Model pom = null; -289 try { -290 if (pomEntries.size() > 1) { -291 //extract POM to its own directory and add it as its own dependency -292 final Dependency newDependency = new Dependency(); -293 pom = extractPom(path, jar, newDependency); -294 -295 final String displayPath = String.format("%s%s%s", -296 dependency.getFilePath(), -297 File.separator, -298 path); -299 final String displayName = String.format("%s%s%s", -300 dependency.getFileName(), -301 File.separator, -302 path); -303 -304 newDependency.setFileName(displayName); -305 newDependency.setFilePath(displayPath); -306 pom.processProperties(pomProperties); -307 setPomEvidence(newDependency, pom, null); -308 engine.getDependencies().add(newDependency); -309 Collections.sort(engine.getDependencies()); -310 } else { -311 if (externalPom == null) { -312 pom = PomUtils.readPom(path, jar); -313 } else { -314 pom = PomUtils.readPom(externalPom); -315 } -316 pom.processProperties(pomProperties); -317 foundSomething |= setPomEvidence(dependency, pom, classes); -318 } -319 } catch (AnalysisException ex) { -320 final String msg = String.format("An error occured while analyzing '%s'.", dependency.getActualFilePath()); -321 LOGGER.log(Level.WARNING, msg); -322 LOGGER.log(Level.FINE, "", ex); -323 } -324 } -325 return foundSomething; -326 } -327 -328 /** -329 * Given a path to a pom.xml within a JarFile, this method attempts to load a sibling pom.properties if one exists. -330 * -331 * @param path the path to the pom.xml within the JarFile -332 * @param jar the JarFile to load the pom.properties from -333 * @return a Properties object or null if no pom.properties was found -334 * @throws IOException thrown if there is an exception reading the pom.properties -335 */ -336 private Properties retrievePomProperties(String path, final JarFile jar) throws IOException { -337 Properties pomProperties = null; -338 final String propPath = path.substring(0, path.length() - 7) + "pom.properies"; -339 final ZipEntry propEntry = jar.getEntry(propPath); -340 if (propEntry != null) { -341 Reader reader = null; -342 try { -343 reader = new InputStreamReader(jar.getInputStream(propEntry), "UTF-8"); -344 pomProperties = new Properties(); -345 pomProperties.load(reader); -346 LOGGER.fine(String.format("Read pom.properties: %s", propPath)); -347 } finally { -348 if (reader != null) { -349 try { -350 reader.close(); -351 } catch (IOException ex) { -352 LOGGER.log(Level.FINEST, "close error", ex); -353 } -354 } -355 } -356 } -357 return pomProperties; -358 } -359 -360 /** -361 * Searches a JarFile for pom.xml entries and returns a listing of these entries. -362 * -363 * @param jar the JarFile to search -364 * @return a list of pom.xml entries -365 * @throws IOException thrown if there is an exception reading a JarEntry -366 */ -367 private List<String> retrievePomListing(final JarFile jar) throws IOException { -368 final List<String> pomEntries = new ArrayList<String>(); -369 final Enumeration<JarEntry> entries = jar.entries(); -370 while (entries.hasMoreElements()) { -371 final JarEntry entry = entries.nextElement(); -372 final String entryName = (new File(entry.getName())).getName().toLowerCase(); -373 if (!entry.isDirectory() && "pom.xml".equals(entryName)) { -374 LOGGER.fine(String.format("POM Entry found: %s", entry.getName())); -375 pomEntries.add(entry.getName()); -376 } -377 } -378 return pomEntries; -379 } -380 -381 /** -382 * Retrieves the specified POM from a jar file and converts it to a Model. -383 * -384 * @param path the path to the pom.xml file within the jar file -385 * @param jar the jar file to extract the pom from -386 * @param dependency the dependency being analyzed -387 * @return returns the POM object -388 * @throws AnalysisException is thrown if there is an exception extracting or parsing the POM -389 * {@link org.owasp.dependencycheck.jaxb.pom.generated.Model} object -390 */ -391 private Model extractPom(String path, JarFile jar, Dependency dependency) throws AnalysisException { -392 InputStream input = null; -393 FileOutputStream fos = null; -394 BufferedOutputStream bos = null; -395 final File tmpDir = getNextTempDirectory(); -396 final File file = new File(tmpDir, "pom.xml"); -397 try { -398 final ZipEntry entry = jar.getEntry(path); -399 input = jar.getInputStream(entry); -400 fos = new FileOutputStream(file); -401 bos = new BufferedOutputStream(fos, BUFFER_SIZE); -402 int count; -403 final byte[] data = new byte[BUFFER_SIZE]; -404 while ((count = input.read(data, 0, BUFFER_SIZE)) != -1) { -405 bos.write(data, 0, count); -406 } -407 bos.flush(); -408 dependency.setActualFilePath(file.getAbsolutePath()); -409 } catch (IOException ex) { -410 final String msg = String.format("An error occurred reading '%s' from '%s'.", path, dependency.getFilePath()); -411 LOGGER.warning(msg); -412 LOGGER.log(Level.SEVERE, "", ex); -413 } finally { -414 closeStream(bos); -415 closeStream(fos); -416 closeStream(input); -417 } -418 return PomUtils.readPom(file); -419 } -420 -421 /** -422 * Silently closes an input stream ignoring errors. -423 * -424 * @param stream an input stream to close -425 */ -426 private void closeStream(InputStream stream) { -427 if (stream != null) { -428 try { -429 stream.close(); -430 } catch (IOException ex) { -431 LOGGER.log(Level.FINEST, null, ex); -432 } -433 } -434 } -435 -436 /** -437 * Silently closes an output stream ignoring errors. -438 * -439 * @param stream an output stream to close -440 */ -441 private void closeStream(OutputStream stream) { -442 if (stream != null) { -443 try { -444 stream.close(); -445 } catch (IOException ex) { -446 LOGGER.log(Level.FINEST, null, ex); -447 } -448 } -449 } -450 -451 /** -452 * Sets evidence from the pom on the supplied dependency. -453 * -454 * @param dependency the dependency to set data on -455 * @param pom the information from the pom -456 * @param classes a collection of ClassNameInformation - containing data about the fully qualified class names within the JAR -457 * file being analyzed -458 * @return true if there was evidence within the pom that we could use; otherwise false -459 */ -460 public static boolean setPomEvidence(Dependency dependency, Model pom, List<ClassNameInformation> classes) { -461 boolean foundSomething = false; -462 boolean addAsIdentifier = true; -463 if (pom == null) { -464 return foundSomething; -465 } -466 String groupid = pom.getGroupId(); -467 String parentGroupId = pom.getParentGroupId(); -468 String artifactid = pom.getArtifactId(); -469 String parentArtifactId = pom.getParentArtifactId(); -470 String version = pom.getVersion(); -471 String parentVersion = pom.getParentVersion(); -472 -473 if ("org.sonatype.oss".equals(parentGroupId) && "oss-parent".equals(parentArtifactId)) { -474 parentGroupId = null; -475 parentArtifactId = null; -476 parentVersion = null; -477 } -478 -479 if ((groupid == null || groupid.isEmpty()) && parentGroupId != null && !parentGroupId.isEmpty()) { -480 groupid = parentGroupId; +261 LOGGER.warn("Unable to read JarFile '{}'.", dependency.getActualFilePath()); +262 LOGGER.trace("", ex); +263 return false; +264 } +265 List<String> pomEntries; +266 try { +267 pomEntries = retrievePomListing(jar); +268 } catch (IOException ex) { +269 LOGGER.warn("Unable to read Jar file entries in '{}'.", dependency.getActualFilePath()); +270 LOGGER.trace("", ex); +271 return false; +272 } +273 File externalPom = null; +274 if (pomEntries.isEmpty()) { +275 String pomPath = dependency.getActualFilePath(); +276 pomPath = pomPath.substring(0, pomPath.lastIndexOf('.')) + ".pom"; +277 externalPom = new File(pomPath); +278 if (externalPom.isFile()) { +279 pomEntries.add(pomPath); +280 } else { +281 return false; +282 } +283 } +284 for (String path : pomEntries) { +285 LOGGER.debug("Reading pom entry: {}", path); +286 Properties pomProperties = null; +287 try { +288 if (externalPom == null) { +289 pomProperties = retrievePomProperties(path, jar); +290 } +291 } catch (IOException ex) { +292 LOGGER.trace("ignore this, failed reading a non-existent pom.properties", ex); +293 } +294 Model pom = null; +295 try { +296 if (pomEntries.size() > 1) { +297 //extract POM to its own directory and add it as its own dependency +298 final Dependency newDependency = new Dependency(); +299 pom = extractPom(path, jar, newDependency); +300 +301 final String displayPath = String.format("%s%s%s", +302 dependency.getFilePath(), +303 File.separator, +304 path); +305 final String displayName = String.format("%s%s%s", +306 dependency.getFileName(), +307 File.separator, +308 path); +309 +310 newDependency.setFileName(displayName); +311 newDependency.setFilePath(displayPath); +312 pom.processProperties(pomProperties); +313 setPomEvidence(newDependency, pom, null); +314 engine.getDependencies().add(newDependency); +315 Collections.sort(engine.getDependencies()); +316 } else { +317 if (externalPom == null) { +318 pom = PomUtils.readPom(path, jar); +319 } else { +320 pom = PomUtils.readPom(externalPom); +321 } +322 pom.processProperties(pomProperties); +323 foundSomething |= setPomEvidence(dependency, pom, classes); +324 } +325 } catch (AnalysisException ex) { +326 LOGGER.warn("An error occured while analyzing '{}'.", dependency.getActualFilePath()); +327 LOGGER.trace("", ex); +328 } +329 } +330 return foundSomething; +331 } +332 +333 /** +334 * Given a path to a pom.xml within a JarFile, this method attempts to load a sibling pom.properties if one exists. +335 * +336 * @param path the path to the pom.xml within the JarFile +337 * @param jar the JarFile to load the pom.properties from +338 * @return a Properties object or null if no pom.properties was found +339 * @throws IOException thrown if there is an exception reading the pom.properties +340 */ +341 private Properties retrievePomProperties(String path, final JarFile jar) throws IOException { +342 Properties pomProperties = null; +343 final String propPath = path.substring(0, path.length() - 7) + "pom.properies"; +344 final ZipEntry propEntry = jar.getEntry(propPath); +345 if (propEntry != null) { +346 Reader reader = null; +347 try { +348 reader = new InputStreamReader(jar.getInputStream(propEntry), "UTF-8"); +349 pomProperties = new Properties(); +350 pomProperties.load(reader); +351 LOGGER.debug("Read pom.properties: {}", propPath); +352 } finally { +353 if (reader != null) { +354 try { +355 reader.close(); +356 } catch (IOException ex) { +357 LOGGER.trace("close error", ex); +358 } +359 } +360 } +361 } +362 return pomProperties; +363 } +364 +365 /** +366 * Searches a JarFile for pom.xml entries and returns a listing of these entries. +367 * +368 * @param jar the JarFile to search +369 * @return a list of pom.xml entries +370 * @throws IOException thrown if there is an exception reading a JarEntry +371 */ +372 private List<String> retrievePomListing(final JarFile jar) throws IOException { +373 final List<String> pomEntries = new ArrayList<String>(); +374 final Enumeration<JarEntry> entries = jar.entries(); +375 while (entries.hasMoreElements()) { +376 final JarEntry entry = entries.nextElement(); +377 final String entryName = (new File(entry.getName())).getName().toLowerCase(); +378 if (!entry.isDirectory() && "pom.xml".equals(entryName)) { +379 LOGGER.trace("POM Entry found: {}", entry.getName()); +380 pomEntries.add(entry.getName()); +381 } +382 } +383 return pomEntries; +384 } +385 +386 /** +387 * Retrieves the specified POM from a jar file and converts it to a Model. +388 * +389 * @param path the path to the pom.xml file within the jar file +390 * @param jar the jar file to extract the pom from +391 * @param dependency the dependency being analyzed +392 * @return returns the POM object +393 * @throws AnalysisException is thrown if there is an exception extracting or parsing the POM +394 * {@link org.owasp.dependencycheck.xml.pom.Model} object +395 */ +396 private Model extractPom(String path, JarFile jar, Dependency dependency) throws AnalysisException { +397 InputStream input = null; +398 FileOutputStream fos = null; +399 BufferedOutputStream bos = null; +400 final File tmpDir = getNextTempDirectory(); +401 final File file = new File(tmpDir, "pom.xml"); +402 try { +403 final ZipEntry entry = jar.getEntry(path); +404 input = jar.getInputStream(entry); +405 fos = new FileOutputStream(file); +406 bos = new BufferedOutputStream(fos, BUFFER_SIZE); +407 int count; +408 final byte[] data = new byte[BUFFER_SIZE]; +409 while ((count = input.read(data, 0, BUFFER_SIZE)) != -1) { +410 bos.write(data, 0, count); +411 } +412 bos.flush(); +413 dependency.setActualFilePath(file.getAbsolutePath()); +414 } catch (IOException ex) { +415 LOGGER.warn("An error occurred reading '{}' from '{}'.", path, dependency.getFilePath()); +416 LOGGER.error("", ex); +417 } finally { +418 closeStream(bos); +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 about the fully qualified class names within the JAR +461 * file being analyzed +462 * @return true if there was evidence within the pom that we could use; otherwise false +463 */ +464 public static boolean setPomEvidence(Dependency dependency, Model pom, List<ClassNameInformation> classes) { +465 boolean foundSomething = false; +466 boolean addAsIdentifier = true; +467 if (pom == null) { +468 return foundSomething; +469 } +470 String groupid = pom.getGroupId(); +471 String parentGroupId = pom.getParentGroupId(); +472 String artifactid = pom.getArtifactId(); +473 String parentArtifactId = pom.getParentArtifactId(); +474 String version = pom.getVersion(); +475 String parentVersion = pom.getParentVersion(); +476 +477 if ("org.sonatype.oss".equals(parentGroupId) && "oss-parent".equals(parentArtifactId)) { +478 parentGroupId = null; +479 parentArtifactId = null; +480 parentVersion = null; 481 } 482 -483 final String originalGroupID = groupid; -484 if (groupid.startsWith("org.") || groupid.startsWith("com.")) { -485 groupid = groupid.substring(4); -486 } -487 -488 if ((artifactid == null || artifactid.isEmpty()) && parentArtifactId != null && !parentArtifactId.isEmpty()) { -489 artifactid = parentArtifactId; +483 if ((groupid == null || groupid.isEmpty()) && parentGroupId != null && !parentGroupId.isEmpty()) { +484 groupid = parentGroupId; +485 } +486 +487 final String originalGroupID = groupid; +488 if (groupid.startsWith("org.") || groupid.startsWith("com.")) { +489 groupid = groupid.substring(4); 490 } 491 -492 final String originalArtifactID = artifactid; -493 if (artifactid.startsWith("org.") || artifactid.startsWith("com.")) { -494 artifactid = artifactid.substring(4); -495 } -496 -497 if ((version == null || version.isEmpty()) && parentVersion != null && !parentVersion.isEmpty()) { -498 version = parentVersion; +492 if ((artifactid == null || artifactid.isEmpty()) && parentArtifactId != null && !parentArtifactId.isEmpty()) { +493 artifactid = parentArtifactId; +494 } +495 +496 final String originalArtifactID = artifactid; +497 if (artifactid.startsWith("org.") || artifactid.startsWith("com.")) { +498 artifactid = artifactid.substring(4); 499 } 500 -501 if (groupid != null && !groupid.isEmpty()) { -502 foundSomething = true; -503 dependency.getVendorEvidence().addEvidence("pom", "groupid", groupid, Confidence.HIGHEST); -504 dependency.getProductEvidence().addEvidence("pom", "groupid", groupid, Confidence.LOW); -505 addMatchingValues(classes, groupid, dependency.getVendorEvidence()); -506 addMatchingValues(classes, groupid, dependency.getProductEvidence()); -507 if (parentGroupId != null && !parentGroupId.isEmpty() && !parentGroupId.equals(groupid)) { -508 dependency.getVendorEvidence().addEvidence("pom", "parent-groupid", parentGroupId, Confidence.MEDIUM); -509 dependency.getProductEvidence().addEvidence("pom", "parent-groupid", parentGroupId, Confidence.LOW); -510 addMatchingValues(classes, parentGroupId, dependency.getVendorEvidence()); -511 addMatchingValues(classes, parentGroupId, dependency.getProductEvidence()); -512 } -513 } else { -514 addAsIdentifier = false; -515 } -516 -517 if (artifactid != null && !artifactid.isEmpty()) { -518 foundSomething = true; -519 dependency.getProductEvidence().addEvidence("pom", "artifactid", artifactid, Confidence.HIGHEST); -520 dependency.getVendorEvidence().addEvidence("pom", "artifactid", artifactid, Confidence.LOW); -521 addMatchingValues(classes, artifactid, dependency.getVendorEvidence()); -522 addMatchingValues(classes, artifactid, dependency.getProductEvidence()); -523 if (parentArtifactId != null && !parentArtifactId.isEmpty() && !parentArtifactId.equals(artifactid)) { -524 dependency.getProductEvidence().addEvidence("pom", "parent-artifactid", parentArtifactId, Confidence.MEDIUM); -525 dependency.getVendorEvidence().addEvidence("pom", "parent-artifactid", parentArtifactId, Confidence.LOW); -526 addMatchingValues(classes, parentArtifactId, dependency.getVendorEvidence()); -527 addMatchingValues(classes, parentArtifactId, dependency.getProductEvidence()); -528 } -529 } else { -530 addAsIdentifier = false; -531 } -532 -533 if (version != null && !version.isEmpty()) { -534 foundSomething = true; -535 dependency.getVersionEvidence().addEvidence("pom", "version", version, Confidence.HIGHEST); -536 if (parentVersion != null && !parentVersion.isEmpty() && !parentVersion.equals(version)) { -537 dependency.getVersionEvidence().addEvidence("pom", "parent-version", version, Confidence.LOW); -538 } -539 } else { -540 addAsIdentifier = false; -541 } -542 -543 if (addAsIdentifier) { -544 dependency.addIdentifier("maven", String.format("%s:%s:%s", originalGroupID, originalArtifactID, version), null, Confidence.HIGH); +501 if ((version == null || version.isEmpty()) && parentVersion != null && !parentVersion.isEmpty()) { +502 version = parentVersion; +503 } +504 +505 if (groupid != null && !groupid.isEmpty()) { +506 foundSomething = true; +507 dependency.getVendorEvidence().addEvidence("pom", "groupid", groupid, Confidence.HIGHEST); +508 dependency.getProductEvidence().addEvidence("pom", "groupid", groupid, Confidence.LOW); +509 addMatchingValues(classes, groupid, dependency.getVendorEvidence()); +510 addMatchingValues(classes, groupid, dependency.getProductEvidence()); +511 if (parentGroupId != null && !parentGroupId.isEmpty() && !parentGroupId.equals(groupid)) { +512 dependency.getVendorEvidence().addEvidence("pom", "parent-groupid", parentGroupId, Confidence.MEDIUM); +513 dependency.getProductEvidence().addEvidence("pom", "parent-groupid", parentGroupId, Confidence.LOW); +514 addMatchingValues(classes, parentGroupId, dependency.getVendorEvidence()); +515 addMatchingValues(classes, parentGroupId, dependency.getProductEvidence()); +516 } +517 } else { +518 addAsIdentifier = false; +519 } +520 +521 if (artifactid != null && !artifactid.isEmpty()) { +522 foundSomething = true; +523 dependency.getProductEvidence().addEvidence("pom", "artifactid", artifactid, Confidence.HIGHEST); +524 dependency.getVendorEvidence().addEvidence("pom", "artifactid", artifactid, Confidence.LOW); +525 addMatchingValues(classes, artifactid, dependency.getVendorEvidence()); +526 addMatchingValues(classes, artifactid, dependency.getProductEvidence()); +527 if (parentArtifactId != null && !parentArtifactId.isEmpty() && !parentArtifactId.equals(artifactid)) { +528 dependency.getProductEvidence().addEvidence("pom", "parent-artifactid", parentArtifactId, Confidence.MEDIUM); +529 dependency.getVendorEvidence().addEvidence("pom", "parent-artifactid", parentArtifactId, Confidence.LOW); +530 addMatchingValues(classes, parentArtifactId, dependency.getVendorEvidence()); +531 addMatchingValues(classes, parentArtifactId, dependency.getProductEvidence()); +532 } +533 } else { +534 addAsIdentifier = false; +535 } +536 +537 if (version != null && !version.isEmpty()) { +538 foundSomething = true; +539 dependency.getVersionEvidence().addEvidence("pom", "version", version, Confidence.HIGHEST); +540 if (parentVersion != null && !parentVersion.isEmpty() && !parentVersion.equals(version)) { +541 dependency.getVersionEvidence().addEvidence("pom", "parent-version", version, Confidence.LOW); +542 } +543 } else { +544 addAsIdentifier = false; 545 } 546 -547 // org name -548 final String org = pom.getOrganization(); -549 if (org != null && !org.isEmpty()) { -550 dependency.getVendorEvidence().addEvidence("pom", "organization name", org, Confidence.HIGH); -551 dependency.getProductEvidence().addEvidence("pom", "organization name", org, Confidence.LOW); -552 addMatchingValues(classes, org, dependency.getVendorEvidence()); -553 addMatchingValues(classes, org, dependency.getProductEvidence()); -554 } -555 //pom name -556 final String pomName = pom.getName(); -557 if (pomName -558 != null && !pomName.isEmpty()) { -559 foundSomething = true; -560 dependency.getProductEvidence().addEvidence("pom", "name", pomName, Confidence.HIGH); -561 dependency.getVendorEvidence().addEvidence("pom", "name", pomName, Confidence.HIGH); -562 addMatchingValues(classes, pomName, dependency.getVendorEvidence()); -563 addMatchingValues(classes, pomName, dependency.getProductEvidence()); -564 } -565 -566 //Description -567 final String description = pom.getDescription(); -568 if (description != null && !description.isEmpty()) { -569 foundSomething = true; -570 final String trimmedDescription = addDescription(dependency, description, "pom", "description"); -571 addMatchingValues(classes, trimmedDescription, dependency.getVendorEvidence()); -572 addMatchingValues(classes, trimmedDescription, dependency.getProductEvidence()); -573 } -574 -575 extractLicense(pom, dependency); -576 return foundSomething; -577 } +547 if (addAsIdentifier) { +548 dependency.addIdentifier("maven", String.format("%s:%s:%s", originalGroupID, originalArtifactID, version), null, Confidence.HIGH); +549 } +550 +551 // org name +552 final String org = pom.getOrganization(); +553 if (org != null && !org.isEmpty()) { +554 dependency.getVendorEvidence().addEvidence("pom", "organization name", org, Confidence.HIGH); +555 dependency.getProductEvidence().addEvidence("pom", "organization name", org, Confidence.LOW); +556 addMatchingValues(classes, org, dependency.getVendorEvidence()); +557 addMatchingValues(classes, org, dependency.getProductEvidence()); +558 } +559 //pom name +560 final String pomName = pom.getName(); +561 if (pomName +562 != null && !pomName.isEmpty()) { +563 foundSomething = true; +564 dependency.getProductEvidence().addEvidence("pom", "name", pomName, Confidence.HIGH); +565 dependency.getVendorEvidence().addEvidence("pom", "name", pomName, Confidence.HIGH); +566 addMatchingValues(classes, pomName, dependency.getVendorEvidence()); +567 addMatchingValues(classes, pomName, dependency.getProductEvidence()); +568 } +569 +570 //Description +571 final String description = pom.getDescription(); +572 if (description != null && !description.isEmpty() && !description.startsWith("POM was created by")) { +573 foundSomething = true; +574 final String trimmedDescription = addDescription(dependency, description, "pom", "description"); +575 addMatchingValues(classes, trimmedDescription, dependency.getVendorEvidence()); +576 addMatchingValues(classes, trimmedDescription, dependency.getProductEvidence()); +577 } 578 -579 /** -580 * Analyzes the path information of the classes contained within the JarAnalyzer to try and determine possible vendor or -581 * product names. If any are found they are stored in the packageVendor and packageProduct hashSets. -582 * -583 * @param classNames a list of class names -584 * @param dependency a dependency to analyze -585 * @param addPackagesAsEvidence a flag indicating whether or not package names should be added as evidence. -586 */ -587 protected void analyzePackageNames(List<ClassNameInformation> classNames, -588 Dependency dependency, boolean addPackagesAsEvidence) { -589 final Map<String, Integer> vendorIdentifiers = new HashMap<String, Integer>(); -590 final Map<String, Integer> productIdentifiers = new HashMap<String, Integer>(); -591 analyzeFullyQualifiedClassNames(classNames, vendorIdentifiers, productIdentifiers); -592 -593 final int classCount = classNames.size(); -594 final EvidenceCollection vendor = dependency.getVendorEvidence(); -595 final EvidenceCollection product = dependency.getProductEvidence(); +579 extractLicense(pom, dependency); +580 return foundSomething; +581 } +582 +583 /** +584 * Analyzes the path information of the classes contained within the JarAnalyzer to try and determine possible vendor or +585 * product names. If any are found they are stored in the packageVendor and packageProduct hashSets. +586 * +587 * @param classNames a list of class names +588 * @param dependency a dependency to analyze +589 * @param addPackagesAsEvidence a flag indicating whether or not package names should be added as evidence. +590 */ +591 protected void analyzePackageNames(List<ClassNameInformation> classNames, +592 Dependency dependency, boolean addPackagesAsEvidence) { +593 final Map<String, Integer> vendorIdentifiers = new HashMap<String, Integer>(); +594 final Map<String, Integer> productIdentifiers = new HashMap<String, Integer>(); +595 analyzeFullyQualifiedClassNames(classNames, vendorIdentifiers, productIdentifiers); 596 -597 for (Map.Entry<String, Integer> entry : vendorIdentifiers.entrySet()) { -598 final float ratio = entry.getValue() / (float) classCount; -599 if (ratio > 0.5) { -600 //TODO remove weighting -601 vendor.addWeighting(entry.getKey()); -602 if (addPackagesAsEvidence && entry.getKey().length() > 1) { -603 vendor.addEvidence("jar", "package name", entry.getKey(), Confidence.LOW); -604 } -605 } -606 } -607 for (Map.Entry<String, Integer> entry : productIdentifiers.entrySet()) { -608 final float ratio = entry.getValue() / (float) classCount; -609 if (ratio > 0.5) { -610 product.addWeighting(entry.getKey()); -611 if (addPackagesAsEvidence && entry.getKey().length() > 1) { -612 product.addEvidence("jar", "package name", entry.getKey(), Confidence.LOW); -613 } -614 } -615 } -616 } -617 -618 /** -619 * <p> -620 * Reads the manifest from the JAR file and collects the entries. Some vendorKey entries are:</p> -621 * <ul><li>Implementation Title</li> -622 * <li>Implementation Version</li> <li>Implementation Vendor</li> -623 * <li>Implementation VendorId</li> <li>Bundle Name</li> <li>Bundle Version</li> <li>Bundle Vendor</li> <li>Bundle -624 * Description</li> <li>Main Class</li> </ul> -625 * However, all but a handful of specific entries are read in. -626 * -627 * @param dependency A reference to the dependency -628 * @param classInformation a collection of class information -629 * @return whether evidence was identified parsing the manifest -630 * @throws IOException if there is an issue reading the JAR file -631 */ -632 protected boolean parseManifest(Dependency dependency, List<ClassNameInformation> classInformation) throws IOException { -633 boolean foundSomething = false; -634 JarFile jar = null; -635 try { -636 jar = new JarFile(dependency.getActualFilePath()); -637 -638 final Manifest manifest = jar.getManifest(); -639 -640 if (manifest == null) { -641 //don't log this for javadoc or sources jar files -642 if (!dependency.getFileName().toLowerCase().endsWith("-sources.jar") -643 && !dependency.getFileName().toLowerCase().endsWith("-javadoc.jar") -644 && !dependency.getFileName().toLowerCase().endsWith("-src.jar") -645 && !dependency.getFileName().toLowerCase().endsWith("-doc.jar")) { -646 LOGGER.log(Level.FINE, -647 String.format("Jar file '%s' does not contain a manifest.", -648 dependency.getFileName())); -649 } -650 return false; -651 } -652 final Attributes atts = manifest.getMainAttributes(); -653 -654 final EvidenceCollection vendorEvidence = dependency.getVendorEvidence(); -655 final EvidenceCollection productEvidence = dependency.getProductEvidence(); -656 final EvidenceCollection versionEvidence = dependency.getVersionEvidence(); -657 -658 final String source = "Manifest"; -659 -660 for (Entry<Object, Object> entry : atts.entrySet()) { -661 String key = entry.getKey().toString(); -662 String value = atts.getValue(key); -663 if (HTML_DETECTION_PATTERN.matcher(value).find()) { -664 value = Jsoup.parse(value).text(); -665 } -666 if (IGNORE_VALUES.contains(value)) { -667 continue; -668 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_TITLE.toString())) { -669 foundSomething = true; -670 productEvidence.addEvidence(source, key, value, Confidence.HIGH); -671 addMatchingValues(classInformation, value, productEvidence); -672 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VERSION.toString())) { -673 foundSomething = true; -674 versionEvidence.addEvidence(source, key, value, Confidence.HIGH); -675 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VENDOR.toString())) { -676 foundSomething = true; -677 vendorEvidence.addEvidence(source, key, value, Confidence.HIGH); -678 addMatchingValues(classInformation, value, vendorEvidence); -679 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VENDOR_ID.toString())) { +597 final int classCount = classNames.size(); +598 final EvidenceCollection vendor = dependency.getVendorEvidence(); +599 final EvidenceCollection product = dependency.getProductEvidence(); +600 +601 for (Map.Entry<String, Integer> entry : vendorIdentifiers.entrySet()) { +602 final float ratio = entry.getValue() / (float) classCount; +603 if (ratio > 0.5) { +604 //TODO remove weighting +605 vendor.addWeighting(entry.getKey()); +606 if (addPackagesAsEvidence && entry.getKey().length() > 1) { +607 vendor.addEvidence("jar", "package name", entry.getKey(), Confidence.LOW); +608 } +609 } +610 } +611 for (Map.Entry<String, Integer> entry : productIdentifiers.entrySet()) { +612 final float ratio = entry.getValue() / (float) classCount; +613 if (ratio > 0.5) { +614 product.addWeighting(entry.getKey()); +615 if (addPackagesAsEvidence && entry.getKey().length() > 1) { +616 product.addEvidence("jar", "package name", entry.getKey(), Confidence.LOW); +617 } +618 } +619 } +620 } +621 +622 /** +623 * <p> +624 * Reads the manifest from the JAR file and collects the entries. Some vendorKey entries are:</p> +625 * <ul><li>Implementation Title</li> +626 * <li>Implementation Version</li> <li>Implementation Vendor</li> +627 * <li>Implementation VendorId</li> <li>Bundle Name</li> <li>Bundle Version</li> <li>Bundle Vendor</li> <li>Bundle +628 * Description</li> <li>Main Class</li> </ul> +629 * However, all but a handful of specific entries are read in. +630 * +631 * @param dependency A reference to the dependency +632 * @param classInformation a collection of class information +633 * @return whether evidence was identified parsing the manifest +634 * @throws IOException if there is an issue reading the JAR file +635 */ +636 protected boolean parseManifest(Dependency dependency, List<ClassNameInformation> classInformation) throws IOException { +637 boolean foundSomething = false; +638 JarFile jar = null; +639 try { +640 jar = new JarFile(dependency.getActualFilePath()); +641 +642 final Manifest manifest = jar.getManifest(); +643 +644 if (manifest == null) { +645 //don't log this for javadoc or sources jar files +646 if (!dependency.getFileName().toLowerCase().endsWith("-sources.jar") +647 && !dependency.getFileName().toLowerCase().endsWith("-javadoc.jar") +648 && !dependency.getFileName().toLowerCase().endsWith("-src.jar") +649 && !dependency.getFileName().toLowerCase().endsWith("-doc.jar")) { +650 LOGGER.debug("Jar file '{}' does not contain a manifest.", +651 dependency.getFileName()); +652 } +653 return false; +654 } +655 final Attributes atts = manifest.getMainAttributes(); +656 +657 final EvidenceCollection vendorEvidence = dependency.getVendorEvidence(); +658 final EvidenceCollection productEvidence = dependency.getProductEvidence(); +659 final EvidenceCollection versionEvidence = dependency.getVersionEvidence(); +660 +661 final String source = "Manifest"; +662 +663 String specificationVersion = null; +664 boolean hasImplementationVersion = false; +665 +666 for (Entry<Object, Object> entry : atts.entrySet()) { +667 String key = entry.getKey().toString(); +668 String value = atts.getValue(key); +669 if (HTML_DETECTION_PATTERN.matcher(value).find()) { +670 value = Jsoup.parse(value).text(); +671 } +672 if (IGNORE_VALUES.contains(value)) { +673 continue; +674 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_TITLE.toString())) { +675 foundSomething = true; +676 productEvidence.addEvidence(source, key, value, Confidence.HIGH); +677 addMatchingValues(classInformation, value, productEvidence); +678 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VERSION.toString())) { +679 hasImplementationVersion = true; 680 foundSomething = true; -681 vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -682 addMatchingValues(classInformation, value, vendorEvidence); -683 } else if (key.equalsIgnoreCase(BUNDLE_DESCRIPTION)) { -684 foundSomething = true; -685 addDescription(dependency, value, "manifest", key); -686 //productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -687 addMatchingValues(classInformation, value, productEvidence); -688 } else if (key.equalsIgnoreCase(BUNDLE_NAME)) { +681 versionEvidence.addEvidence(source, key, value, Confidence.HIGH); +682 } else if ("specification-version".equalsIgnoreCase(key)) { +683 specificationVersion = key; +684 } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VENDOR.toString())) { +685 foundSomething = true; +686 vendorEvidence.addEvidence(source, key, value, Confidence.HIGH); +687 addMatchingValues(classInformation, value, vendorEvidence); +688 } else if (key.equalsIgnoreCase(IMPLEMENTATION_VENDOR_ID)) { 689 foundSomething = true; -690 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -691 addMatchingValues(classInformation, value, productEvidence); -692 } else if (key.equalsIgnoreCase(BUNDLE_VENDOR)) { +690 vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +691 addMatchingValues(classInformation, value, vendorEvidence); +692 } else if (key.equalsIgnoreCase(BUNDLE_DESCRIPTION)) { 693 foundSomething = true; -694 vendorEvidence.addEvidence(source, key, value, Confidence.HIGH); -695 addMatchingValues(classInformation, value, vendorEvidence); -696 } else if (key.equalsIgnoreCase(BUNDLE_VERSION)) { -697 foundSomething = true; -698 versionEvidence.addEvidence(source, key, value, Confidence.HIGH); -699 } else if (key.equalsIgnoreCase(Attributes.Name.MAIN_CLASS.toString())) { -700 continue; -701 //skipping main class as if this has important information to add -702 // it will be added during class name analysis... if other fields -703 // have the information from the class name then they will get added... -704 // foundSomething = true; -705 // productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -706 // vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -707 // addMatchingValues(classInformation, value, vendorEvidence); -708 // addMatchingValues(classInformation, value, productEvidence); -709 } else { -710 key = key.toLowerCase(); -711 -712 if (!IGNORE_KEYS.contains(key) -713 && !key.endsWith("jdk") -714 && !key.contains("lastmodified") -715 && !key.endsWith("package") -716 && !key.endsWith("classpath") -717 && !key.endsWith("class-path") -718 && !key.endsWith("-scm") //todo change this to a regex? -719 && !key.startsWith("scm-") -720 && !value.trim().startsWith("scm:") -721 && !isImportPackage(key, value) -722 && !isPackage(key, value)) { -723 -724 foundSomething = true; -725 if (key.contains("version")) { -726 if (key.contains("specification")) { -727 versionEvidence.addEvidence(source, key, value, Confidence.LOW); -728 } else { -729 versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -730 } -731 } else if ("build-id".equals(key)) { -732 int pos = value.indexOf('('); -733 if (pos >= 0) { -734 value = value.substring(0, pos - 1); -735 } -736 pos = value.indexOf('['); -737 if (pos >= 0) { -738 value = value.substring(0, pos - 1); -739 } -740 versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -741 } else if (key.contains("title")) { -742 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -743 addMatchingValues(classInformation, value, productEvidence); -744 } else if (key.contains("vendor")) { -745 if (key.contains("specification")) { -746 vendorEvidence.addEvidence(source, key, value, Confidence.LOW); -747 } else { -748 vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -749 addMatchingValues(classInformation, value, vendorEvidence); -750 } -751 } else if (key.contains("name")) { +694 addDescription(dependency, value, "manifest", key); +695 //productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +696 addMatchingValues(classInformation, value, productEvidence); +697 } else if (key.equalsIgnoreCase(BUNDLE_NAME)) { +698 foundSomething = true; +699 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +700 addMatchingValues(classInformation, value, productEvidence); +701 // //the following caused false positives. +702 // } else if (key.equalsIgnoreCase(BUNDLE_VENDOR)) { +703 // foundSomething = true; +704 // vendorEvidence.addEvidence(source, key, value, Confidence.HIGH); +705 // addMatchingValues(classInformation, value, vendorEvidence); +706 } else if (key.equalsIgnoreCase(BUNDLE_VERSION)) { +707 foundSomething = true; +708 versionEvidence.addEvidence(source, key, value, Confidence.HIGH); +709 } else if (key.equalsIgnoreCase(Attributes.Name.MAIN_CLASS.toString())) { +710 continue; +711 //skipping main class as if this has important information to add +712 // it will be added during class name analysis... if other fields +713 // have the information from the class name then they will get added... +714 // foundSomething = true; +715 // productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +716 // vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +717 // addMatchingValues(classInformation, value, vendorEvidence); +718 // addMatchingValues(classInformation, value, productEvidence); +719 } else { +720 key = key.toLowerCase(); +721 +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 +734 foundSomething = true; +735 if (key.contains("version")) { +736 if (!key.contains("specification")) { +737 //versionEvidence.addEvidence(source, key, value, Confidence.LOW); +738 //} else { +739 versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +740 } +741 } else if ("build-id".equals(key)) { +742 int pos = value.indexOf('('); +743 if (pos >= 0) { +744 value = value.substring(0, pos - 1); +745 } +746 pos = value.indexOf('['); +747 if (pos >= 0) { +748 value = value.substring(0, pos - 1); +749 } +750 versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +751 } else if (key.contains("title")) { 752 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -753 vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM); -754 addMatchingValues(classInformation, value, vendorEvidence); -755 addMatchingValues(classInformation, value, productEvidence); -756 } else if (key.contains("license")) { -757 addLicense(dependency, value); -758 } else { -759 if (key.contains("description")) { -760 addDescription(dependency, value, "manifest", key); -761 } else { -762 productEvidence.addEvidence(source, key, value, Confidence.LOW); -763 vendorEvidence.addEvidence(source, key, value, Confidence.LOW); -764 addMatchingValues(classInformation, value, vendorEvidence); -765 addMatchingValues(classInformation, value, productEvidence); -766 if (value.matches(".*\\d.*")) { -767 final StringTokenizer tokenizer = new StringTokenizer(value, " "); -768 while (tokenizer.hasMoreElements()) { -769 final String s = tokenizer.nextToken(); -770 if (s.matches("^[0-9.]+$")) { -771 versionEvidence.addEvidence(source, key, s, Confidence.LOW); -772 } -773 } -774 } -775 } -776 } -777 } -778 } -779 } -780 } finally { -781 if (jar != null) { -782 jar.close(); -783 } -784 } -785 return foundSomething; -786 } -787 -788 /** -789 * Adds a description to the given dependency. If the description contains one of the following strings beyond 100 characters, -790 * then the description used will be trimmed to that position: -791 * <ul><li>"such as"</li><li>"like "</li><li>"will use "</li><li>"* uses "</li></ul> -792 * -793 * @param dependency a dependency -794 * @param description the description -795 * @param source the source of the evidence -796 * @param key the "name" of the evidence -797 * @return if the description is trimmed, the trimmed version is returned; otherwise the original description is returned -798 */ -799 public static String addDescription(Dependency dependency, String description, String source, String key) { -800 if (dependency.getDescription() == null) { -801 dependency.setDescription(description); -802 } -803 String desc; -804 if (HTML_DETECTION_PATTERN.matcher(description).find()) { -805 desc = Jsoup.parse(description).text(); -806 } else { -807 desc = description; -808 } -809 dependency.setDescription(desc); -810 if (desc.length() > 100) { -811 desc = desc.replaceAll("\\s\\s+", " "); -812 final int posSuchAs = desc.toLowerCase().indexOf("such as ", 100); -813 final int posLike = desc.toLowerCase().indexOf("like ", 100); -814 final int posWillUse = desc.toLowerCase().indexOf("will use ", 100); -815 final int posUses = desc.toLowerCase().indexOf(" uses ", 100); -816 int pos = -1; -817 pos = Math.max(pos, posSuchAs); -818 if (pos >= 0 && posLike >= 0) { -819 pos = Math.min(pos, posLike); -820 } else { -821 pos = Math.max(pos, posLike); -822 } -823 if (pos >= 0 && posWillUse >= 0) { -824 pos = Math.min(pos, posWillUse); -825 } else { -826 pos = Math.max(pos, posWillUse); -827 } -828 if (pos >= 0 && posUses >= 0) { -829 pos = Math.min(pos, posUses); -830 } else { -831 pos = Math.max(pos, posUses); -832 } -833 -834 if (pos > 0) { -835 final StringBuilder sb = new StringBuilder(pos + 3); -836 sb.append(desc.substring(0, pos)); -837 sb.append("..."); -838 desc = sb.toString(); -839 } -840 dependency.getProductEvidence().addEvidence(source, key, desc, Confidence.LOW); -841 dependency.getVendorEvidence().addEvidence(source, key, desc, Confidence.LOW); -842 } else { -843 dependency.getProductEvidence().addEvidence(source, key, desc, Confidence.MEDIUM); -844 dependency.getVendorEvidence().addEvidence(source, key, desc, Confidence.MEDIUM); -845 } -846 return desc; -847 } -848 -849 /** -850 * Adds a license to the given dependency. -851 * -852 * @param d a dependency -853 * @param license the license -854 */ -855 private void addLicense(Dependency d, String license) { -856 if (d.getLicense() == null) { -857 d.setLicense(license); -858 } else if (!d.getLicense().contains(license)) { -859 d.setLicense(d.getLicense() + NEWLINE + license); -860 } +753 addMatchingValues(classInformation, value, productEvidence); +754 } else if (key.contains("vendor")) { +755 if (key.contains("specification")) { +756 vendorEvidence.addEvidence(source, key, value, Confidence.LOW); +757 } else { +758 vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +759 addMatchingValues(classInformation, value, vendorEvidence); +760 } +761 } else if (key.contains("name")) { +762 productEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +763 vendorEvidence.addEvidence(source, key, value, Confidence.MEDIUM); +764 addMatchingValues(classInformation, value, vendorEvidence); +765 addMatchingValues(classInformation, value, productEvidence); +766 } else if (key.contains("license")) { +767 addLicense(dependency, value); +768 } else { +769 if (key.contains("description")) { +770 addDescription(dependency, value, "manifest", key); +771 } else { +772 productEvidence.addEvidence(source, key, value, Confidence.LOW); +773 vendorEvidence.addEvidence(source, key, value, Confidence.LOW); +774 addMatchingValues(classInformation, value, vendorEvidence); +775 addMatchingValues(classInformation, value, productEvidence); +776 if (value.matches(".*\\d.*")) { +777 final StringTokenizer tokenizer = new StringTokenizer(value, " "); +778 while (tokenizer.hasMoreElements()) { +779 final String s = tokenizer.nextToken(); +780 if (s.matches("^[0-9.]+$")) { +781 versionEvidence.addEvidence(source, key, s, Confidence.LOW); +782 } +783 } +784 } +785 } +786 } +787 } +788 } +789 } +790 if (specificationVersion != null && !hasImplementationVersion) { +791 foundSomething = true; +792 versionEvidence.addEvidence(source, "specificationn-version", specificationVersion, Confidence.HIGH); +793 } +794 } finally { +795 if (jar != null) { +796 jar.close(); +797 } +798 } +799 return foundSomething; +800 } +801 +802 /** +803 * Adds a description to the given dependency. If the description contains one of the following strings beyond 100 characters, +804 * then the description used will be trimmed to that position: +805 * <ul><li>"such as"</li><li>"like "</li><li>"will use "</li><li>"* uses "</li></ul> +806 * +807 * @param dependency a dependency +808 * @param description the description +809 * @param source the source of the evidence +810 * @param key the "name" of the evidence +811 * @return if the description is trimmed, the trimmed version is returned; otherwise the original description is returned +812 */ +813 public static String addDescription(Dependency dependency, String description, String source, String key) { +814 if (dependency.getDescription() == null) { +815 dependency.setDescription(description); +816 } +817 String desc; +818 if (HTML_DETECTION_PATTERN.matcher(description).find()) { +819 desc = Jsoup.parse(description).text(); +820 } else { +821 desc = description; +822 } +823 dependency.setDescription(desc); +824 if (desc.length() > 100) { +825 desc = desc.replaceAll("\\s\\s+", " "); +826 final int posSuchAs = desc.toLowerCase().indexOf("such as ", 100); +827 final int posLike = desc.toLowerCase().indexOf("like ", 100); +828 final int posWillUse = desc.toLowerCase().indexOf("will use ", 100); +829 final int posUses = desc.toLowerCase().indexOf(" uses ", 100); +830 int pos = -1; +831 pos = Math.max(pos, posSuchAs); +832 if (pos >= 0 && posLike >= 0) { +833 pos = Math.min(pos, posLike); +834 } else { +835 pos = Math.max(pos, posLike); +836 } +837 if (pos >= 0 && posWillUse >= 0) { +838 pos = Math.min(pos, posWillUse); +839 } else { +840 pos = Math.max(pos, posWillUse); +841 } +842 if (pos >= 0 && posUses >= 0) { +843 pos = Math.min(pos, posUses); +844 } else { +845 pos = Math.max(pos, posUses); +846 } +847 +848 if (pos > 0) { +849 final StringBuilder sb = new StringBuilder(pos + 3); +850 sb.append(desc.substring(0, pos)); +851 sb.append("..."); +852 desc = sb.toString(); +853 } +854 dependency.getProductEvidence().addEvidence(source, key, desc, Confidence.LOW); +855 dependency.getVendorEvidence().addEvidence(source, key, desc, Confidence.LOW); +856 } else { +857 dependency.getProductEvidence().addEvidence(source, key, desc, Confidence.MEDIUM); +858 dependency.getVendorEvidence().addEvidence(source, key, desc, Confidence.MEDIUM); +859 } +860 return desc; 861 } 862 863 /** -864 * The parent directory for the individual directories per archive. -865 */ -866 private File tempFileLocation = null; -867 -868 /** -869 * Initializes the JarAnalyzer. -870 * -871 * @throws Exception is thrown if there is an exception creating a temporary directory -872 */ -873 @Override -874 public void initializeFileTypeAnalyzer() throws Exception { -875 final File baseDir = Settings.getTempDirectory(); -876 tempFileLocation = File.createTempFile("check", "tmp", baseDir); -877 if (!tempFileLocation.delete()) { -878 final String msg = String.format("Unable to delete temporary file '%s'.", tempFileLocation.getAbsolutePath()); -879 throw new AnalysisException(msg); -880 } -881 if (!tempFileLocation.mkdirs()) { -882 final String msg = String.format("Unable to create directory '%s'.", tempFileLocation.getAbsolutePath()); -883 throw new AnalysisException(msg); -884 } -885 } -886 -887 /** -888 * Deletes any files extracted from the JAR during analysis. -889 */ -890 @Override -891 public void close() { -892 if (tempFileLocation != null && tempFileLocation.exists()) { -893 LOGGER.log(Level.FINE, "Attempting to delete temporary files"); -894 final boolean success = FileUtils.delete(tempFileLocation); -895 if (!success) { -896 LOGGER.log(Level.WARNING, -897 "Failed to delete some temporary files, see the log for more details"); -898 } -899 } -900 } -901 -902 /** -903 * Determines if the key value pair from the manifest is for an "import" type entry for package names. -904 * -905 * @param key the key from the manifest -906 * @param value the value from the manifest -907 * @return true or false depending on if it is believed the entry is an "import" entry -908 */ -909 private boolean isImportPackage(String key, String value) { -910 final Pattern packageRx = Pattern.compile("^([a-zA-Z0-9_#\\$\\*\\.]+\\s*[,;]\\s*)+([a-zA-Z0-9_#\\$\\*\\.]+\\s*)?$"); -911 final boolean matches = packageRx.matcher(value).matches(); -912 return matches && (key.contains("import") || key.contains("include") || value.length() > 10); +864 * Adds a license to the given dependency. +865 * +866 * @param d a dependency +867 * @param license the license +868 */ +869 private void addLicense(Dependency d, String license) { +870 if (d.getLicense() == null) { +871 d.setLicense(license); +872 } else if (!d.getLicense().contains(license)) { +873 d.setLicense(d.getLicense() + NEWLINE + license); +874 } +875 } +876 +877 /** +878 * The parent directory for the individual directories per archive. +879 */ +880 private File tempFileLocation = null; +881 +882 /** +883 * Initializes the JarAnalyzer. +884 * +885 * @throws Exception is thrown if there is an exception creating a temporary directory +886 */ +887 @Override +888 public void initializeFileTypeAnalyzer() throws Exception { +889 final File baseDir = Settings.getTempDirectory(); +890 tempFileLocation = File.createTempFile("check", "tmp", baseDir); +891 if (!tempFileLocation.delete()) { +892 final String msg = String.format("Unable to delete temporary file '%s'.", tempFileLocation.getAbsolutePath()); +893 throw new AnalysisException(msg); +894 } +895 if (!tempFileLocation.mkdirs()) { +896 final String msg = String.format("Unable to create directory '%s'.", tempFileLocation.getAbsolutePath()); +897 throw new AnalysisException(msg); +898 } +899 } +900 +901 /** +902 * Deletes any files extracted from the JAR during analysis. +903 */ +904 @Override +905 public void close() { +906 if (tempFileLocation != null && tempFileLocation.exists()) { +907 LOGGER.debug("Attempting to delete temporary files"); +908 final boolean success = FileUtils.delete(tempFileLocation); +909 if (!success) { +910 LOGGER.warn("Failed to delete some temporary files, see the log for more details"); +911 } +912 } 913 } 914 915 /** -916 * Cycles through an enumeration of JarEntries, contained within the dependency, and returns a list of the class names. This -917 * does not include core Java package names (i.e. java.* or javax.*). -918 * -919 * @param dependency the dependency being analyzed -920 * @return an list of fully qualified class names +916 * Determines if the key value pair from the manifest is for an "import" type entry for package names. +917 * +918 * @param key the key from the manifest +919 * @param value the value from the manifest +920 * @return true or false depending on if it is believed the entry is an "import" entry 921 */ -922 private List<ClassNameInformation> collectClassNames(Dependency dependency) { -923 final List<ClassNameInformation> classNames = new ArrayList<ClassNameInformation>(); -924 JarFile jar = null; -925 try { -926 jar = new JarFile(dependency.getActualFilePath()); -927 final Enumeration entries = jar.entries(); -928 while (entries.hasMoreElements()) { -929 final JarEntry entry = (JarEntry) entries.nextElement(); -930 final String name = entry.getName().toLowerCase(); -931 //no longer stripping "|com\\.sun" - there are some com.sun jar files with CVEs. -932 if (name.endsWith(".class") && !name.matches("^javax?\\..*$")) { -933 final ClassNameInformation className = new ClassNameInformation(name.substring(0, name.length() - 6)); -934 classNames.add(className); -935 } -936 } -937 } catch (IOException ex) { -938 final String msg = String.format("Unable to open jar file '%s'.", dependency.getFileName()); -939 LOGGER.log(Level.WARNING, msg); -940 LOGGER.log(Level.FINE, null, ex); -941 } finally { -942 if (jar != null) { -943 try { -944 jar.close(); -945 } catch (IOException ex) { -946 LOGGER.log(Level.FINEST, null, ex); -947 } -948 } -949 } -950 return classNames; -951 } -952 -953 /** -954 * Cycles through the list of class names and places the package levels 0-3 into the provided maps for vendor and product. -955 * This is helpful when analyzing vendor/product as many times this is included in the package name. -956 * -957 * @param classNames a list of class names -958 * @param vendor HashMap of possible vendor names from package names (e.g. owasp) -959 * @param product HashMap of possible product names from package names (e.g. dependencycheck) -960 */ -961 private void analyzeFullyQualifiedClassNames(List<ClassNameInformation> classNames, -962 Map<String, Integer> vendor, Map<String, Integer> product) { -963 for (ClassNameInformation entry : classNames) { -964 final List<String> list = entry.getPackageStructure(); -965 addEntry(vendor, list.get(0)); -966 -967 if (list.size() == 2) { -968 addEntry(product, list.get(1)); -969 } -970 if (list.size() == 3) { -971 addEntry(vendor, list.get(1)); -972 addEntry(product, list.get(1)); -973 addEntry(product, list.get(2)); -974 } -975 if (list.size() >= 4) { -976 addEntry(vendor, list.get(1)); -977 addEntry(vendor, list.get(2)); -978 addEntry(product, list.get(1)); -979 addEntry(product, list.get(2)); -980 addEntry(product, list.get(3)); +922 private boolean isImportPackage(String key, String value) { +923 final Pattern packageRx = Pattern.compile("^([a-zA-Z0-9_#\\$\\*\\.]+\\s*[,;]\\s*)+([a-zA-Z0-9_#\\$\\*\\.]+\\s*)?$"); +924 final boolean matches = packageRx.matcher(value).matches(); +925 return matches && (key.contains("import") || key.contains("include") || value.length() > 10); +926 } +927 +928 /** +929 * Cycles through an enumeration of JarEntries, contained within the dependency, and returns a list of the class names. This +930 * does not include core Java package names (i.e. java.* or javax.*). +931 * +932 * @param dependency the dependency being analyzed +933 * @return an list of fully qualified class names +934 */ +935 private List<ClassNameInformation> collectClassNames(Dependency dependency) { +936 final List<ClassNameInformation> classNames = new ArrayList<ClassNameInformation>(); +937 JarFile jar = null; +938 try { +939 jar = new JarFile(dependency.getActualFilePath()); +940 final Enumeration<JarEntry> entries = jar.entries(); +941 while (entries.hasMoreElements()) { +942 final JarEntry entry = entries.nextElement(); +943 final String name = entry.getName().toLowerCase(); +944 //no longer stripping "|com\\.sun" - there are some com.sun jar files with CVEs. +945 if (name.endsWith(".class") && !name.matches("^javax?\\..*$")) { +946 final ClassNameInformation className = new ClassNameInformation(name.substring(0, name.length() - 6)); +947 classNames.add(className); +948 } +949 } +950 } catch (IOException ex) { +951 LOGGER.warn("Unable to open jar file '{}'.", dependency.getFileName()); +952 LOGGER.debug("", ex); +953 } finally { +954 if (jar != null) { +955 try { +956 jar.close(); +957 } catch (IOException ex) { +958 LOGGER.trace("", ex); +959 } +960 } +961 } +962 return classNames; +963 } +964 +965 /** +966 * Cycles through the list of class names and places the package levels 0-3 into the provided maps for vendor and product. +967 * This is helpful when analyzing vendor/product as many times this is included in the package name. +968 * +969 * @param classNames a list of class names +970 * @param vendor HashMap of possible vendor names from package names (e.g. owasp) +971 * @param product HashMap of possible product names from package names (e.g. dependencycheck) +972 */ +973 private void analyzeFullyQualifiedClassNames(List<ClassNameInformation> classNames, +974 Map<String, Integer> vendor, Map<String, Integer> product) { +975 for (ClassNameInformation entry : classNames) { +976 final List<String> list = entry.getPackageStructure(); +977 addEntry(vendor, list.get(0)); +978 +979 if (list.size() == 2) { +980 addEntry(product, list.get(1)); 981 } -982 } -983 } -984 -985 /** -986 * Adds an entry to the specified collection and sets the Integer (e.g. the count) to 1. If the entry already exists in the -987 * collection then the Integer is incremented by 1. -988 * -989 * @param collection a collection of strings and their occurrence count -990 * @param key the key to add to the collection -991 */ -992 private void addEntry(Map<String, Integer> collection, String key) { -993 if (collection.containsKey(key)) { -994 collection.put(key, collection.get(key) + 1); -995 } else { -996 collection.put(key, 1); -997 } -998 } -999 -1000 /** -1001 * Cycles through the collection of class name information to see if parts of the package names are contained in the provided -1002 * value. If found, it will be added as the HIGHEST confidence evidence because we have more then one source corroborating the -1003 * value. -1004 * -1005 * @param classes a collection of class name information -1006 * @param value the value to check to see if it contains a package name -1007 * @param evidence the evidence collection to add new entries too -1008 */ -1009 private static void addMatchingValues(List<ClassNameInformation> classes, String value, EvidenceCollection evidence) { -1010 if (value == null || value.isEmpty() || classes == null || classes.isEmpty()) { -1011 return; -1012 } -1013 final String text = value.toLowerCase(); -1014 for (ClassNameInformation cni : classes) { -1015 for (String key : cni.getPackageStructure()) { -1016 if (text.contains(key)) { //note, package structure elements are already lowercase. -1017 evidence.addEvidence("jar", "package name", key, Confidence.HIGHEST); -1018 } -1019 } -1020 } -1021 } -1022 -1023 /** -1024 * Simple check to see if the attribute from a manifest is just a package name. -1025 * -1026 * @param key the key of the value to check -1027 * @param value the value to check -1028 * @return true if the value looks like a java package name, otherwise false -1029 */ -1030 private boolean isPackage(String key, String value) { -1031 -1032 return !key.matches(".*(version|title|vendor|name|license|description).*") -1033 && value.matches("^([a-zA-Z_][a-zA-Z0-9_\\$]*(\\.[a-zA-Z_][a-zA-Z0-9_\\$]*)*)?$"); +982 if (list.size() == 3) { +983 addEntry(vendor, list.get(1)); +984 addEntry(product, list.get(1)); +985 addEntry(product, list.get(2)); +986 } +987 if (list.size() >= 4) { +988 addEntry(vendor, list.get(1)); +989 addEntry(vendor, list.get(2)); +990 addEntry(product, list.get(1)); +991 addEntry(product, list.get(2)); +992 addEntry(product, list.get(3)); +993 } +994 } +995 } +996 +997 /** +998 * Adds an entry to the specified collection and sets the Integer (e.g. the count) to 1. If the entry already exists in the +999 * collection then the Integer is incremented by 1. +1000 * +1001 * @param collection a collection of strings and their occurrence count +1002 * @param key the key to add to the collection +1003 */ +1004 private void addEntry(Map<String, Integer> collection, String key) { +1005 if (collection.containsKey(key)) { +1006 collection.put(key, collection.get(key) + 1); +1007 } else { +1008 collection.put(key, 1); +1009 } +1010 } +1011 +1012 /** +1013 * Cycles through the collection of class name information to see if parts of the package names are contained in the provided +1014 * value. If found, it will be added as the HIGHEST confidence evidence because we have more then one source corroborating the +1015 * value. +1016 * +1017 * @param classes a collection of class name information +1018 * @param value the value to check to see if it contains a package name +1019 * @param evidence the evidence collection to add new entries too +1020 */ +1021 private static void addMatchingValues(List<ClassNameInformation> classes, String value, EvidenceCollection evidence) { +1022 if (value == null || value.isEmpty() || classes == null || classes.isEmpty()) { +1023 return; +1024 } +1025 final String text = value.toLowerCase(); +1026 for (ClassNameInformation cni : classes) { +1027 for (String key : cni.getPackageStructure()) { +1028 if (text.contains(key)) { //note, package structure elements are already lowercase. +1029 evidence.addEvidence("jar", "package name", key, Confidence.HIGHEST); +1030 } +1031 } +1032 } +1033 } 1034 -1035 } -1036 -1037 /** -1038 * Extracts the license information from the pom and adds it to the dependency. -1039 * -1040 * @param pom the pom object -1041 * @param dependency the dependency to add license information too -1042 */ -1043 public static void extractLicense(Model pom, Dependency dependency) { -1044 //license -1045 if (pom.getLicenses() != null) { -1046 String license = null; -1047 for (License lic : pom.getLicenses()) { -1048 String tmp = null; -1049 if (lic.getName() != null) { -1050 tmp = lic.getName(); -1051 } -1052 if (lic.getUrl() != null) { -1053 if (tmp == null) { -1054 tmp = lic.getUrl(); -1055 } else { -1056 tmp += ": " + lic.getUrl(); -1057 } -1058 } -1059 if (tmp == null) { -1060 continue; -1061 } -1062 if (HTML_DETECTION_PATTERN.matcher(tmp).find()) { -1063 tmp = Jsoup.parse(tmp).text(); -1064 } -1065 if (license == null) { -1066 license = tmp; -1067 } else { -1068 license += "\n" + tmp; -1069 } -1070 } -1071 if (license != null) { -1072 dependency.setLicense(license); -1073 -1074 } -1075 } -1076 } -1077 -1078 /** -1079 * Stores information about a class name. -1080 */ -1081 protected static class ClassNameInformation { -1082 -1083 /** -1084 * <p> -1085 * Stores information about a given class name. This class will keep the fully qualified class name and a list of the -1086 * important parts of the package structure. Up to the first four levels of the package structure are stored, excluding a -1087 * leading "org" or "com". Example:</p> -1088 * <code>ClassNameInformation obj = new ClassNameInformation("org.owasp.dependencycheck.analyzer.JarAnalyzer"); -1089 * System.out.println(obj.getName()); -1090 * for (String p : obj.getPackageStructure()) -1091 * System.out.println(p); -1092 * </code> -1093 * <p> -1094 * Would result in:</p> -1095 * <code>org.owasp.dependencycheck.analyzer.JarAnalyzer -1096 * owasp -1097 * dependencycheck -1098 * analyzer -1099 * jaranalyzer</code> -1100 * -1101 * @param className a fully qualified class name -1102 */ -1103 ClassNameInformation(String className) { -1104 name = className; -1105 if (name.contains("/")) { -1106 final String[] tmp = className.toLowerCase().split("/"); -1107 int start = 0; -1108 int end = 3; -1109 if ("com".equals(tmp[0]) || "org".equals(tmp[0])) { -1110 start = 1; -1111 end = 4; -1112 } -1113 if (tmp.length <= end) { -1114 end = tmp.length - 1; -1115 } -1116 for (int i = start; i <= end; i++) { -1117 packageStructure.add(tmp[i]); -1118 } -1119 } else { -1120 packageStructure.add(name); -1121 } -1122 } -1123 /** -1124 * The fully qualified class name. -1125 */ -1126 private String name; -1127 -1128 /** -1129 * Get the value of name -1130 * -1131 * @return the value of name -1132 */ -1133 public String getName() { -1134 return name; -1135 } -1136 -1137 /** -1138 * Set the value of name -1139 * -1140 * @param name new value of name -1141 */ -1142 public void setName(String name) { -1143 this.name = name; -1144 } -1145 /** -1146 * Up to the first four levels of the package structure, excluding a leading "org" or "com". -1147 */ -1148 private final ArrayList<String> packageStructure = new ArrayList<String>(); -1149 -1150 /** -1151 * Get the value of packageStructure -1152 * -1153 * @return the value of packageStructure -1154 */ -1155 public ArrayList<String> getPackageStructure() { -1156 return packageStructure; -1157 } -1158 } -1159 -1160 /** -1161 * Retrieves the next temporary directory to extract an archive too. -1162 * -1163 * @return a directory -1164 * @throws AnalysisException thrown if unable to create temporary directory -1165 */ -1166 private File getNextTempDirectory() throws AnalysisException { -1167 dirCount += 1; -1168 final File directory = new File(tempFileLocation, String.valueOf(dirCount)); -1169 //getting an exception for some directories not being able to be created; might be because the directory already exists? -1170 if (directory.exists()) { -1171 return getNextTempDirectory(); -1172 } -1173 if (!directory.mkdirs()) { -1174 final String msg = String.format("Unable to create temp directory '%s'.", directory.getAbsolutePath()); -1175 throw new AnalysisException(msg); -1176 } -1177 return directory; -1178 } -1179 } +1035 /** +1036 * Simple check to see if the attribute from a manifest is just a package name. +1037 * +1038 * @param key the key of the value to check +1039 * @param value the value to check +1040 * @return true if the value looks like a java package name, otherwise false +1041 */ +1042 private boolean isPackage(String key, String value) { +1043 +1044 return !key.matches(".*(version|title|vendor|name|license|description).*") +1045 && value.matches("^([a-zA-Z_][a-zA-Z0-9_\\$]*(\\.[a-zA-Z_][a-zA-Z0-9_\\$]*)*)?$"); +1046 +1047 } +1048 +1049 /** +1050 * Extracts the license information from the pom and adds it to the dependency. +1051 * +1052 * @param pom the pom object +1053 * @param dependency the dependency to add license information too +1054 */ +1055 public static void extractLicense(Model pom, Dependency dependency) { +1056 //license +1057 if (pom.getLicenses() != null) { +1058 String license = null; +1059 for (License lic : pom.getLicenses()) { +1060 String tmp = null; +1061 if (lic.getName() != null) { +1062 tmp = lic.getName(); +1063 } +1064 if (lic.getUrl() != null) { +1065 if (tmp == null) { +1066 tmp = lic.getUrl(); +1067 } else { +1068 tmp += ": " + lic.getUrl(); +1069 } +1070 } +1071 if (tmp == null) { +1072 continue; +1073 } +1074 if (HTML_DETECTION_PATTERN.matcher(tmp).find()) { +1075 tmp = Jsoup.parse(tmp).text(); +1076 } +1077 if (license == null) { +1078 license = tmp; +1079 } else { +1080 license += "\n" + tmp; +1081 } +1082 } +1083 if (license != null) { +1084 dependency.setLicense(license); +1085 +1086 } +1087 } +1088 } +1089 +1090 /** +1091 * Stores information about a class name. +1092 */ +1093 protected static class ClassNameInformation { +1094 +1095 /** +1096 * <p> +1097 * Stores information about a given class name. This class will keep the fully qualified class name and a list of the +1098 * important parts of the package structure. Up to the first four levels of the package structure are stored, excluding a +1099 * leading "org" or "com". Example:</p> +1100 * <code>ClassNameInformation obj = new ClassNameInformation("org.owasp.dependencycheck.analyzer.JarAnalyzer"); +1101 * System.out.println(obj.getName()); +1102 * for (String p : obj.getPackageStructure()) +1103 * System.out.println(p); +1104 * </code> +1105 * <p> +1106 * Would result in:</p> +1107 * <code>org.owasp.dependencycheck.analyzer.JarAnalyzer +1108 * owasp +1109 * dependencycheck +1110 * analyzer +1111 * jaranalyzer</code> +1112 * +1113 * @param className a fully qualified class name +1114 */ +1115 ClassNameInformation(String className) { +1116 name = className; +1117 if (name.contains("/")) { +1118 final String[] tmp = className.toLowerCase().split("/"); +1119 int start = 0; +1120 int end = 3; +1121 if ("com".equals(tmp[0]) || "org".equals(tmp[0])) { +1122 start = 1; +1123 end = 4; +1124 } +1125 if (tmp.length <= end) { +1126 end = tmp.length - 1; +1127 } +1128 for (int i = start; i <= end; i++) { +1129 packageStructure.add(tmp[i]); +1130 } +1131 } else { +1132 packageStructure.add(name); +1133 } +1134 } +1135 /** +1136 * The fully qualified class name. +1137 */ +1138 private String name; +1139 +1140 /** +1141 * Get the value of name +1142 * +1143 * @return the value of name +1144 */ +1145 public String getName() { +1146 return name; +1147 } +1148 +1149 /** +1150 * Set the value of name +1151 * +1152 * @param name new value of name +1153 */ +1154 public void setName(String name) { +1155 this.name = name; +1156 } +1157 /** +1158 * Up to the first four levels of the package structure, excluding a leading "org" or "com". +1159 */ +1160 private final ArrayList<String> packageStructure = new ArrayList<String>(); +1161 +1162 /** +1163 * Get the value of packageStructure +1164 * +1165 * @return the value of packageStructure +1166 */ +1167 public ArrayList<String> getPackageStructure() { +1168 return packageStructure; +1169 } +1170 } +1171 +1172 /** +1173 * Retrieves the next temporary directory to extract an archive too. +1174 * +1175 * @return a directory +1176 * @throws AnalysisException thrown if unable to create temporary directory +1177 */ +1178 private File getNextTempDirectory() throws AnalysisException { +1179 dirCount += 1; +1180 final File directory = new File(tempFileLocation, String.valueOf(dirCount)); +1181 //getting an exception for some directories not being able to be created; might be because the directory already exists? +1182 if (directory.exists()) { +1183 return getNextTempDirectory(); +1184 } +1185 if (!directory.mkdirs()) { +1186 final String msg = String.format("Unable to create temp directory '%s'.", directory.getAbsolutePath()); +1187 throw new AnalysisException(msg); +1188 } +1189 return directory; +1190 } +1191 }
    diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/NexusAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/NexusAnalyzer.html index 70c97a2b6..b388a48f3 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/NexusAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/NexusAnalyzer.html @@ -25,242 +25,247 @@ 17 */ 18 package org.owasp.dependencycheck.analyzer; 19 -20 import java.io.File; -21 import java.io.FileNotFoundException; -22 import java.io.IOException; -23 import java.net.MalformedURLException; -24 import java.net.URL; -25 import java.util.Set; -26 import java.util.logging.Level; -27 import java.util.logging.Logger; -28 import org.apache.commons.io.FileUtils; -29 import org.owasp.dependencycheck.Engine; -30 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; -31 import org.owasp.dependencycheck.data.nexus.MavenArtifact; -32 import org.owasp.dependencycheck.data.nexus.NexusSearch; -33 import org.owasp.dependencycheck.dependency.Confidence; -34 import org.owasp.dependencycheck.dependency.Dependency; -35 import org.owasp.dependencycheck.dependency.Evidence; -36 import org.owasp.dependencycheck.xml.pom.PomUtils; -37 import org.owasp.dependencycheck.utils.InvalidSettingException; +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.data.nexus.MavenArtifact; +24 import org.owasp.dependencycheck.data.nexus.NexusSearch; +25 import org.owasp.dependencycheck.dependency.Confidence; +26 import org.owasp.dependencycheck.dependency.Dependency; +27 import org.owasp.dependencycheck.dependency.Evidence; +28 import org.owasp.dependencycheck.xml.pom.PomUtils; +29 import org.slf4j.Logger; +30 import org.slf4j.LoggerFactory; +31 +32 import java.io.File; +33 import java.io.FileFilter; +34 import java.io.FileNotFoundException; +35 import java.io.IOException; +36 import java.net.MalformedURLException; +37 import java.net.URL; 38 import org.owasp.dependencycheck.utils.DownloadFailedException; 39 import org.owasp.dependencycheck.utils.Downloader; -40 import org.owasp.dependencycheck.utils.Settings; -41 -42 /** -43 * Analyzer which will attempt to locate a dependency on a Nexus service by SHA-1 digest of the dependency. -44 * -45 * There are two settings which govern this behavior: +40 import org.owasp.dependencycheck.utils.FileFilterBuilder; +41 import org.owasp.dependencycheck.utils.InvalidSettingException; +42 import org.owasp.dependencycheck.utils.Settings; +43 +44 /** +45 * Analyzer which will attempt to locate a dependency on a Nexus service by SHA-1 digest of the dependency. 46 * -47 * <ul> -48 * <li>{@link org.owasp.dependencycheck.utils.Settings.KEYS#ANALYZER_NEXUS_ENABLED} determines whether this analyzer is even -49 * enabled. This can be overridden by setting the system property.</li> -50 * <li>{@link org.owasp.dependencycheck.utils.Settings.KEYS#ANALYZER_NEXUS_URL} the URL to a Nexus service to search by SHA-1. -51 * There is an expected <code>%s</code> in this where the SHA-1 will get entered.</li> -52 * </ul> -53 * -54 * @author colezlaw -55 */ -56 public class NexusAnalyzer extends AbstractFileTypeAnalyzer { -57 -58 /** -59 * The default URL - this will be used by the CentralAnalyzer to determine whether to enable this. -60 */ -61 public static final String DEFAULT_URL = "https://repository.sonatype.org/service/local/"; -62 -63 /** -64 * The logger. -65 */ -66 private static final Logger LOGGER = Logger.getLogger(NexusAnalyzer.class.getName()); -67 -68 /** -69 * The name of the analyzer. -70 */ -71 private static final String ANALYZER_NAME = "Nexus Analyzer"; -72 -73 /** -74 * The phase in which the analyzer runs. -75 */ -76 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; -77 -78 /** -79 * The types of files on which this will work. -80 */ -81 private static final Set<String> SUPPORTED_EXTENSIONS = newHashSet("jar"); -82 -83 /** -84 * The Nexus Search to be set up for this analyzer. -85 */ -86 private NexusSearch searcher; -87 -88 /** -89 * Field indicating if the analyzer is enabled. -90 */ -91 private final boolean enabled = checkEnabled(); -92 -93 /** -94 * Determines if this analyzer is enabled -95 * -96 * @return <code>true</code> if the analyzer is enabled; otherwise <code>false</code> -97 */ -98 private boolean checkEnabled() { -99 /* Enable this analyzer ONLY if the Nexus URL has been set to something -100 other than the default one (if it's the default one, we'll use the -101 central one) and it's enabled by the user. -102 */ -103 boolean retval = false; -104 try { -105 if ((!DEFAULT_URL.equals(Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL))) -106 && Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED)) { -107 LOGGER.info("Enabling Nexus analyzer"); -108 retval = true; -109 } else { -110 LOGGER.fine("Nexus analyzer disabled, using Central instead"); -111 } -112 } catch (InvalidSettingException ise) { -113 LOGGER.warning("Invalid setting. Disabling Nexus analyzer"); -114 } -115 -116 return retval; -117 } -118 -119 /** -120 * Determine whether to enable this analyzer or not. -121 * -122 * @return whether the analyzer should be enabled -123 */ -124 @Override -125 public boolean isEnabled() { -126 return enabled; -127 } -128 -129 /** -130 * Initializes the analyzer once before any analysis is performed. -131 * -132 * @throws Exception if there's an error during initialization -133 */ -134 @Override -135 public void initializeFileTypeAnalyzer() throws Exception { -136 LOGGER.fine("Initializing Nexus Analyzer"); -137 LOGGER.fine(String.format("Nexus Analyzer enabled: %s", isEnabled())); -138 if (isEnabled()) { -139 final String searchUrl = Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL); -140 LOGGER.fine(String.format("Nexus Analyzer URL: %s", searchUrl)); -141 try { -142 searcher = new NexusSearch(new URL(searchUrl)); -143 if (!searcher.preflightRequest()) { -144 LOGGER.warning("There was an issue getting Nexus status. Disabling analyzer."); -145 setEnabled(false); -146 } -147 } catch (MalformedURLException mue) { -148 // I know that initialize can throw an exception, but we'll -149 // just disable the analyzer if the URL isn't valid -150 LOGGER.warning(String.format("Property %s not a valid URL. Nexus Analyzer disabled", searchUrl)); -151 setEnabled(false); -152 } -153 } -154 } -155 -156 /** -157 * Returns the analyzer's name. -158 * -159 * @return the name of the analyzer -160 */ -161 @Override -162 public String getName() { -163 return ANALYZER_NAME; -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_NEXUS_ENABLED; -174 } -175 -176 /** -177 * Returns the analysis phase under which the analyzer runs. -178 * -179 * @return the phase under which this analyzer runs -180 */ -181 @Override -182 public AnalysisPhase getAnalysisPhase() { -183 return ANALYSIS_PHASE; -184 } -185 -186 /** -187 * Returns the extensions for which this Analyzer runs. -188 * -189 * @return the extensions for which this Analyzer runs +47 * There are two settings which govern this behavior: +48 * +49 * <ul> +50 * <li>{@link org.owasp.dependencycheck.utils.Settings.KEYS#ANALYZER_NEXUS_ENABLED} determines whether this analyzer is even +51 * enabled. This can be overridden by setting the system property.</li> +52 * <li>{@link org.owasp.dependencycheck.utils.Settings.KEYS#ANALYZER_NEXUS_URL} the URL to a Nexus service to search by SHA-1. +53 * There is an expected <code>%s</code> in this where the SHA-1 will get entered.</li> +54 * </ul> +55 * +56 * @author colezlaw +57 */ +58 public class NexusAnalyzer extends AbstractFileTypeAnalyzer { +59 +60 /** +61 * The default URL - this will be used by the CentralAnalyzer to determine whether to enable this. +62 */ +63 public static final String DEFAULT_URL = "https://repository.sonatype.org/service/local/"; +64 +65 /** +66 * The logger. +67 */ +68 private static final Logger LOGGER = LoggerFactory.getLogger(NexusAnalyzer.class); +69 +70 /** +71 * The name of the analyzer. +72 */ +73 private static final String ANALYZER_NAME = "Nexus Analyzer"; +74 +75 /** +76 * The phase in which the analyzer runs. +77 */ +78 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; +79 +80 /** +81 * The types of files on which this will work. +82 */ +83 private static final String SUPPORTED_EXTENSIONS = "jar"; +84 +85 /** +86 * The Nexus Search to be set up for this analyzer. +87 */ +88 private NexusSearch searcher; +89 +90 /** +91 * Field indicating if the analyzer is enabled. +92 */ +93 private final boolean enabled = checkEnabled(); +94 +95 /** +96 * Determines if this analyzer is enabled +97 * +98 * @return <code>true</code> if the analyzer is enabled; otherwise <code>false</code> +99 */ +100 private boolean checkEnabled() { +101 /* Enable this analyzer ONLY if the Nexus URL has been set to something +102 other than the default one (if it's the default one, we'll use the +103 central one) and it's enabled by the user. +104 */ +105 boolean retval = false; +106 try { +107 if ((!DEFAULT_URL.equals(Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL))) +108 && Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED)) { +109 LOGGER.info("Enabling Nexus analyzer"); +110 retval = true; +111 } else { +112 LOGGER.debug("Nexus analyzer disabled, using Central instead"); +113 } +114 } catch (InvalidSettingException ise) { +115 LOGGER.warn("Invalid setting. Disabling Nexus analyzer"); +116 } +117 +118 return retval; +119 } +120 +121 /** +122 * Determine whether to enable this analyzer or not. +123 * +124 * @return whether the analyzer should be enabled +125 */ +126 @Override +127 public boolean isEnabled() { +128 return enabled; +129 } +130 +131 /** +132 * Initializes the analyzer once before any analysis is performed. +133 * +134 * @throws Exception if there's an error during initialization +135 */ +136 @Override +137 public void initializeFileTypeAnalyzer() throws Exception { +138 LOGGER.debug("Initializing Nexus Analyzer"); +139 LOGGER.debug("Nexus Analyzer enabled: {}", isEnabled()); +140 if (isEnabled()) { +141 final String searchUrl = Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL); +142 LOGGER.debug("Nexus Analyzer URL: {}", searchUrl); +143 try { +144 searcher = new NexusSearch(new URL(searchUrl)); +145 if (!searcher.preflightRequest()) { +146 LOGGER.warn("There was an issue getting Nexus status. Disabling analyzer."); +147 setEnabled(false); +148 } +149 } catch (MalformedURLException mue) { +150 // I know that initialize can throw an exception, but we'll +151 // just disable the analyzer if the URL isn't valid +152 LOGGER.warn("Property {} not a valid URL. Nexus Analyzer disabled", searchUrl); +153 setEnabled(false); +154 } +155 } +156 } +157 +158 /** +159 * Returns the analyzer's name. +160 * +161 * @return the name of the analyzer +162 */ +163 @Override +164 public String getName() { +165 return ANALYZER_NAME; +166 } +167 +168 /** +169 * Returns the key used in the properties file to reference the analyzer's enabled property. +170 * +171 * @return the analyzer's enabled property setting key +172 */ +173 @Override +174 protected String getAnalyzerEnabledSettingKey() { +175 return Settings.KEYS.ANALYZER_NEXUS_ENABLED; +176 } +177 +178 /** +179 * Returns the analysis phase under which the analyzer runs. +180 * +181 * @return the phase under which this analyzer runs +182 */ +183 @Override +184 public AnalysisPhase getAnalysisPhase() { +185 return ANALYSIS_PHASE; +186 } +187 +188 /** +189 * The file filter used to determine which files this analyzer supports. 190 */ -191 @Override -192 public Set<String> getSupportedExtensions() { -193 return SUPPORTED_EXTENSIONS; -194 } -195 -196 /** -197 * Performs the analysis. -198 * -199 * @param dependency the dependency to analyze -200 * @param engine the engine -201 * @throws AnalysisException when there's an exception during analysis -202 */ -203 @Override -204 public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { -205 if (!isEnabled()) { -206 return; -207 } -208 try { -209 final MavenArtifact ma = searcher.searchSha1(dependency.getSha1sum()); -210 dependency.addAsEvidence("nexus", ma, Confidence.HIGH); -211 boolean pomAnalyzed = false; -212 LOGGER.fine("POM URL " + ma.getPomUrl()); -213 for (Evidence e : dependency.getVendorEvidence()) { -214 if ("pom".equals(e.getSource())) { -215 pomAnalyzed = true; -216 break; -217 } -218 } -219 if (!pomAnalyzed && ma.getPomUrl() != null) { -220 File pomFile = null; -221 try { -222 final File baseDir = Settings.getTempDirectory(); -223 pomFile = File.createTempFile("pom", ".xml", baseDir); -224 if (!pomFile.delete()) { -225 final String msg = String.format("Unable to fetch pom.xml for %s from Nexus repository; " -226 + "this could result in undetected CPE/CVEs.", dependency.getFileName()); -227 LOGGER.warning(msg); -228 LOGGER.fine("Unable to delete temp file"); -229 } -230 LOGGER.fine(String.format("Downloading %s", ma.getPomUrl())); -231 Downloader.fetchFile(new URL(ma.getPomUrl()), pomFile); -232 PomUtils.analyzePOM(dependency, pomFile); -233 } catch (DownloadFailedException ex) { -234 final String msg = String.format("Unable to download pom.xml for %s from Nexus repository; " -235 + "this could result in undetected CPE/CVEs.", dependency.getFileName()); -236 LOGGER.warning(msg); -237 } finally { -238 if (pomFile != null && !FileUtils.deleteQuietly(pomFile)) { -239 pomFile.deleteOnExit(); -240 } -241 } -242 } -243 } catch (IllegalArgumentException iae) { -244 //dependency.addAnalysisException(new AnalysisException("Invalid SHA-1")); -245 LOGGER.info(String.format("invalid sha-1 hash on %s", dependency.getFileName())); -246 } catch (FileNotFoundException fnfe) { -247 //dependency.addAnalysisException(new AnalysisException("Artifact not found on repository")); -248 LOGGER.fine(String.format("Artifact not found in repository '%s'", dependency.getFileName())); -249 LOGGER.log(Level.FINE, fnfe.getMessage(), fnfe); -250 } catch (IOException ioe) { -251 //dependency.addAnalysisException(new AnalysisException("Could not connect to repository", ioe)); -252 LOGGER.log(Level.FINE, "Could not connect to nexus repository", ioe); -253 } -254 } -255 } +191 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(SUPPORTED_EXTENSIONS).build(); +192 +193 /** +194 * Returns the FileFilter +195 * +196 * @return the FileFilter +197 */ +198 @Override +199 protected FileFilter getFileFilter() { +200 return FILTER; +201 } +202 +203 /** +204 * Performs the analysis. +205 * +206 * @param dependency the dependency to analyze +207 * @param engine the engine +208 * @throws AnalysisException when there's an exception during analysis +209 */ +210 @Override +211 public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { +212 if (!isEnabled()) { +213 return; +214 } +215 try { +216 final MavenArtifact ma = searcher.searchSha1(dependency.getSha1sum()); +217 dependency.addAsEvidence("nexus", ma, Confidence.HIGH); +218 boolean pomAnalyzed = false; +219 LOGGER.debug("POM URL {}", ma.getPomUrl()); +220 for (Evidence e : dependency.getVendorEvidence()) { +221 if ("pom".equals(e.getSource())) { +222 pomAnalyzed = true; +223 break; +224 } +225 } +226 if (!pomAnalyzed && ma.getPomUrl() != null) { +227 File pomFile = null; +228 try { +229 final File baseDir = Settings.getTempDirectory(); +230 pomFile = File.createTempFile("pom", ".xml", baseDir); +231 if (!pomFile.delete()) { +232 LOGGER.warn("Unable to fetch pom.xml for {} from Nexus repository; " +233 + "this could result in undetected CPE/CVEs.", dependency.getFileName()); +234 LOGGER.debug("Unable to delete temp file"); +235 } +236 LOGGER.debug("Downloading {}", ma.getPomUrl()); +237 Downloader.fetchFile(new URL(ma.getPomUrl()), pomFile); +238 PomUtils.analyzePOM(dependency, pomFile); +239 } catch (DownloadFailedException ex) { +240 LOGGER.warn("Unable to download pom.xml for {} from Nexus repository; " +241 + "this could result in undetected CPE/CVEs.", dependency.getFileName()); +242 } finally { +243 if (pomFile != null && !FileUtils.deleteQuietly(pomFile)) { +244 pomFile.deleteOnExit(); +245 } +246 } +247 } +248 } catch (IllegalArgumentException iae) { +249 //dependency.addAnalysisException(new AnalysisException("Invalid SHA-1")); +250 LOGGER.info(String.format("invalid sha-1 hash on %s", dependency.getFileName())); +251 } catch (FileNotFoundException fnfe) { +252 //dependency.addAnalysisException(new AnalysisException("Artifact not found on repository")); +253 LOGGER.debug("Artifact not found in repository '{}'", dependency.getFileName()); +254 LOGGER.debug(fnfe.getMessage(), fnfe); +255 } catch (IOException ioe) { +256 //dependency.addAnalysisException(new AnalysisException("Could not connect to repository", ioe)); +257 LOGGER.debug("Could not connect to nexus repository", ioe); +258 } +259 } +260 }
    diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/NuspecAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/NuspecAnalyzer.html index 95c5003d1..b6fa073e9 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/NuspecAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/NuspecAnalyzer.html @@ -25,143 +25,151 @@ 17 */ 18 package org.owasp.dependencycheck.analyzer; 19 -20 import java.io.FileInputStream; -21 import java.io.FileNotFoundException; -22 import java.io.IOException; -23 import java.util.Set; -24 import java.util.logging.Level; -25 import java.util.logging.Logger; -26 import org.owasp.dependencycheck.Engine; -27 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; -28 import org.owasp.dependencycheck.data.nuget.NugetPackage; -29 import org.owasp.dependencycheck.data.nuget.NuspecParseException; -30 import org.owasp.dependencycheck.data.nuget.NuspecParser; -31 import org.owasp.dependencycheck.data.nuget.XPathNuspecParser; -32 import org.owasp.dependencycheck.dependency.Confidence; -33 import org.owasp.dependencycheck.dependency.Dependency; -34 import org.owasp.dependencycheck.utils.Settings; -35 -36 /** -37 * Analyzer which will parse a Nuspec file to gather module information. -38 * -39 * @author colezlaw -40 */ -41 public class NuspecAnalyzer extends AbstractFileTypeAnalyzer { -42 -43 /** -44 * The logger. -45 */ -46 private static final Logger LOGGER = Logger.getLogger(NuspecAnalyzer.class.getName()); -47 -48 /** -49 * The name of the analyzer. -50 */ -51 private static final String ANALYZER_NAME = "Nuspec Analyzer"; -52 -53 /** -54 * The phase in which the analyzer runs. -55 */ -56 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; -57 -58 /** -59 * The types of files on which this will work. -60 */ -61 private static final Set<String> SUPPORTED_EXTENSIONS = newHashSet("nuspec"); -62 -63 /** -64 * Initializes the analyzer once before any analysis is performed. -65 * -66 * @throws Exception if there's an error during initialization -67 */ -68 @Override -69 public void initializeFileTypeAnalyzer() throws Exception { -70 } -71 -72 /** -73 * Returns the analyzer's name. -74 * -75 * @return the name of the analyzer -76 */ -77 @Override -78 public String getName() { -79 return ANALYZER_NAME; -80 } -81 -82 /** -83 * Returns the key used in the properties file to reference the analyzer's enabled property. -84 * -85 * @return the analyzer's enabled property setting key -86 */ -87 @Override -88 protected String getAnalyzerEnabledSettingKey() { -89 return Settings.KEYS.ANALYZER_NUSPEC_ENABLED; -90 } -91 -92 /** -93 * Returns the analysis phase under which the analyzer runs. -94 * -95 * @return the phase under which this analyzer runs -96 */ -97 @Override -98 public AnalysisPhase getAnalysisPhase() { -99 return ANALYSIS_PHASE; -100 } -101 -102 /** -103 * Returns the extensions for which this Analyzer runs. -104 * -105 * @return the extensions for which this Analyzer runs +20 import org.owasp.dependencycheck.Engine; +21 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; +22 import org.owasp.dependencycheck.data.nuget.NugetPackage; +23 import org.owasp.dependencycheck.data.nuget.NuspecParseException; +24 import org.owasp.dependencycheck.data.nuget.NuspecParser; +25 import org.owasp.dependencycheck.data.nuget.XPathNuspecParser; +26 import org.owasp.dependencycheck.dependency.Confidence; +27 import org.owasp.dependencycheck.dependency.Dependency; +28 import org.owasp.dependencycheck.utils.FileFilterBuilder; +29 import org.owasp.dependencycheck.utils.Settings; +30 import org.slf4j.Logger; +31 import org.slf4j.LoggerFactory; +32 +33 import java.io.FileFilter; +34 import java.io.FileInputStream; +35 import java.io.FileNotFoundException; +36 import java.io.IOException; +37 +38 /** +39 * Analyzer which will parse a Nuspec file to gather module information. +40 * +41 * @author colezlaw +42 */ +43 public class NuspecAnalyzer extends AbstractFileTypeAnalyzer { +44 +45 /** +46 * The logger. +47 */ +48 private static final Logger LOGGER = LoggerFactory.getLogger(NuspecAnalyzer.class); +49 +50 /** +51 * The name of the analyzer. +52 */ +53 private static final String ANALYZER_NAME = "Nuspec Analyzer"; +54 +55 /** +56 * The phase in which the analyzer runs. +57 */ +58 private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; +59 +60 /** +61 * The types of files on which this will work. +62 */ +63 private static final String SUPPORTED_EXTENSIONS = "nuspec"; +64 +65 /** +66 * Initializes the analyzer once before any analysis is performed. +67 * +68 * @throws Exception if there's an error during initialization +69 */ +70 @Override +71 public void initializeFileTypeAnalyzer() throws Exception { +72 } +73 +74 /** +75 * Returns the analyzer's name. +76 * +77 * @return the name of the analyzer +78 */ +79 @Override +80 public String getName() { +81 return ANALYZER_NAME; +82 } +83 +84 /** +85 * Returns the key used in the properties file to reference the analyzer's enabled property. +86 * +87 * @return the analyzer's enabled property setting key +88 */ +89 @Override +90 protected String getAnalyzerEnabledSettingKey() { +91 return Settings.KEYS.ANALYZER_NUSPEC_ENABLED; +92 } +93 +94 /** +95 * Returns the analysis phase under which the analyzer runs. +96 * +97 * @return the phase under which this analyzer runs +98 */ +99 @Override +100 public AnalysisPhase getAnalysisPhase() { +101 return ANALYSIS_PHASE; +102 } +103 +104 /** +105 * The file filter used to determine which files this analyzer supports. 106 */ -107 @Override -108 public Set<String> getSupportedExtensions() { -109 return SUPPORTED_EXTENSIONS; -110 } -111 -112 /** -113 * Performs the analysis. -114 * -115 * @param dependency the dependency to analyze -116 * @param engine the engine -117 * @throws AnalysisException when there's an exception during analysis -118 */ -119 @Override -120 public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { -121 LOGGER.log(Level.FINE, "Checking Nuspec file {0}", dependency.toString()); -122 try { -123 final NuspecParser parser = new XPathNuspecParser(); -124 NugetPackage np = null; -125 FileInputStream fis = null; -126 try { -127 fis = new FileInputStream(dependency.getActualFilePath()); -128 np = parser.parse(fis); -129 } catch (NuspecParseException ex) { -130 throw new AnalysisException(ex); -131 } catch (FileNotFoundException ex) { -132 throw new AnalysisException(ex); -133 } finally { -134 if (fis != null) { -135 try { -136 fis.close(); -137 } catch (IOException e) { -138 LOGGER.fine("Error closing input stream"); -139 } -140 } -141 } -142 -143 if (np.getOwners() != null) { -144 dependency.getVendorEvidence().addEvidence("nuspec", "owners", np.getOwners(), Confidence.HIGHEST); -145 } -146 dependency.getVendorEvidence().addEvidence("nuspec", "authors", np.getAuthors(), Confidence.HIGH); -147 dependency.getVersionEvidence().addEvidence("nuspec", "version", np.getVersion(), Confidence.HIGHEST); -148 dependency.getProductEvidence().addEvidence("nuspec", "id", np.getId(), Confidence.HIGHEST); -149 if (np.getTitle() != null) { -150 dependency.getProductEvidence().addEvidence("nuspec", "title", np.getTitle(), Confidence.MEDIUM); -151 } -152 } catch (Throwable e) { -153 throw new AnalysisException(e); -154 } -155 } -156 } +107 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions( +108 SUPPORTED_EXTENSIONS).build(); +109 +110 /** +111 * Returns the FileFilter +112 * +113 * @return the FileFilter +114 */ +115 @Override +116 protected FileFilter getFileFilter() { +117 return FILTER; +118 } +119 +120 /** +121 * Performs the analysis. +122 * +123 * @param dependency the dependency to analyze +124 * @param engine the engine +125 * @throws AnalysisException when there's an exception during analysis +126 */ +127 @Override +128 public void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { +129 LOGGER.debug("Checking Nuspec file {}", dependency.toString()); +130 try { +131 final NuspecParser parser = new XPathNuspecParser(); +132 NugetPackage np = null; +133 FileInputStream fis = null; +134 try { +135 fis = new FileInputStream(dependency.getActualFilePath()); +136 np = parser.parse(fis); +137 } catch (NuspecParseException ex) { +138 throw new AnalysisException(ex); +139 } catch (FileNotFoundException ex) { +140 throw new AnalysisException(ex); +141 } finally { +142 if (fis != null) { +143 try { +144 fis.close(); +145 } catch (IOException e) { +146 LOGGER.debug("Error closing input stream"); +147 } +148 } +149 } +150 +151 if (np.getOwners() != null) { +152 dependency.getVendorEvidence().addEvidence("nuspec", "owners", np.getOwners(), Confidence.HIGHEST); +153 } +154 dependency.getVendorEvidence().addEvidence("nuspec", "authors", np.getAuthors(), Confidence.HIGH); +155 dependency.getVersionEvidence().addEvidence("nuspec", "version", np.getVersion(), Confidence.HIGHEST); +156 dependency.getProductEvidence().addEvidence("nuspec", "id", np.getId(), Confidence.HIGHEST); +157 if (np.getTitle() != null) { +158 dependency.getProductEvidence().addEvidence("nuspec", "title", np.getTitle(), Confidence.MEDIUM); +159 } +160 } catch (Throwable e) { +161 throw new AnalysisException(e); +162 } +163 } +164 }
    diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/OpenSSLAnalyzer.html b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/OpenSSLAnalyzer.html new file mode 100644 index 000000000..79859721b --- /dev/null +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/OpenSSLAnalyzer.html @@ -0,0 +1,188 @@ + + + +OpenSSLAnalyzer 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) 2015 Institute for Defense Analyses. All Rights Reserved.
    +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.utils.FileFilterBuilder;
    +26  import org.owasp.dependencycheck.utils.Settings;
    +27  
    +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 <dvisser@ida.org>
    +38   */
    +39  public class OpenSSLAnalyzer extends AbstractFileTypeAnalyzer {
    +40  
    +41      private static final int HEXADECIMAL = 16;
    +42      /**
    +43       * Filename to analyze. All other .h files get removed from consideration.
    +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  
    +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
    +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 }
    +
    +
    + + + 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 754eeb00e..a5eaf909a 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/PythonDistributionAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/PythonDistributionAnalyzer.html @@ -27,353 +27,361 @@ 19 20 import java.io.BufferedInputStream; 21 import java.io.File; -22 import java.io.FileInputStream; -23 import java.io.FileNotFoundException; -24 import java.io.FilenameFilter; -25 import java.util.Set; -26 import java.util.logging.Level; -27 import java.util.logging.Logger; -28 import java.util.regex.Pattern; -29 -30 import javax.mail.MessagingException; -31 import javax.mail.internet.InternetHeaders; -32 -33 import org.apache.commons.io.filefilter.NameFileFilter; -34 import org.apache.commons.io.filefilter.SuffixFileFilter; -35 import org.apache.commons.io.input.AutoCloseInputStream; -36 import org.apache.commons.lang.StringUtils; -37 import org.owasp.dependencycheck.Engine; -38 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; -39 import org.owasp.dependencycheck.dependency.Confidence; -40 import org.owasp.dependencycheck.dependency.Dependency; -41 import org.owasp.dependencycheck.dependency.EvidenceCollection; -42 import org.owasp.dependencycheck.utils.ExtractionException; -43 import org.owasp.dependencycheck.utils.ExtractionUtil; -44 import org.owasp.dependencycheck.utils.FileUtils; -45 import org.owasp.dependencycheck.utils.Settings; -46 import org.owasp.dependencycheck.utils.UrlStringUtils; -47 -48 /** -49 * Used to analyze a Wheel or egg distribution files, or their contents in unzipped form, and collect information that can be used -50 * to determine the associated CPE. -51 * -52 * @author Dale Visser <dvisser@ida.org> -53 */ -54 public class PythonDistributionAnalyzer extends AbstractFileTypeAnalyzer { -55 -56 /** -57 * Name of egg metatdata 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 = Logger -70 .getLogger(PythonDistributionAnalyzer.class.getName()); -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 Set<String> EXTENSIONS = newHashSet("whl", "egg", -90 "zip", METADATA, PKG_INFO); -91 -92 /** -93 * Used to match on egg archive candidate extenssions. -94 */ -95 private static final Pattern EGG_OR_ZIP = Pattern.compile("egg|zip"); -96 -97 /** -98 * The parent directory for the individual directories per archive. -99 */ -100 private File tempFileLocation; -101 -102 /** -103 * Filter that detects *.dist-info files (but doesn't verify they are directories. -104 */ -105 private static final FilenameFilter DIST_INFO_FILTER = new SuffixFileFilter( -106 ".dist-info"); -107 -108 /** -109 * Filter that detects files named "METADATA". -110 */ -111 private static final FilenameFilter EGG_INFO_FILTER = new NameFileFilter( -112 "EGG-INFO"); -113 -114 /** -115 * Filter that detects files named "METADATA". -116 */ -117 private static final FilenameFilter METADATA_FILTER = new NameFileFilter( -118 METADATA); -119 -120 /** -121 * Filter that detects files named "PKG-INFO". -122 */ -123 private static final FilenameFilter PKG_INFO_FILTER = new NameFileFilter( -124 PKG_INFO); -125 -126 /** -127 * Returns a list of file EXTENSIONS supported by this analyzer. -128 * -129 * @return a list of file EXTENSIONS supported by this analyzer. -130 */ -131 @Override -132 public Set<String> getSupportedExtensions() { -133 return EXTENSIONS; -134 } -135 -136 /** -137 * Returns the name of the analyzer. -138 * -139 * @return the name of the analyzer. -140 */ -141 @Override -142 public String getName() { -143 return ANALYZER_NAME; -144 } -145 -146 /** -147 * Returns the phase that the analyzer is intended to run in. -148 * -149 * @return the phase that the analyzer is intended to run in. -150 */ -151 public AnalysisPhase getAnalysisPhase() { -152 return ANALYSIS_PHASE; +22 import java.io.FileFilter; +23 import java.io.FileInputStream; +24 import java.io.FileNotFoundException; +25 import java.io.FilenameFilter; +26 import org.apache.commons.io.filefilter.NameFileFilter; +27 import org.apache.commons.io.filefilter.SuffixFileFilter; +28 import org.apache.commons.io.input.AutoCloseInputStream; +29 import org.apache.commons.lang.StringUtils; +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.slf4j.Logger; +36 import org.slf4j.LoggerFactory; +37 +38 import javax.mail.MessagingException; +39 import javax.mail.internet.InternetHeaders; +40 import org.owasp.dependencycheck.utils.ExtractionException; +41 import org.owasp.dependencycheck.utils.ExtractionUtil; +42 import org.owasp.dependencycheck.utils.FileFilterBuilder; +43 import org.owasp.dependencycheck.utils.FileUtils; +44 import org.owasp.dependencycheck.utils.Settings; +45 import org.owasp.dependencycheck.utils.UrlStringUtils; +46 +47 /** +48 * Used to analyze a Wheel or egg distribution files, or their contents in unzipped form, and collect information that can be used +49 * to determine the associated CPE. +50 * +51 * @author Dale Visser <dvisser@ida.org> +52 */ +53 public class PythonDistributionAnalyzer extends AbstractFileTypeAnalyzer { +54 +55 /** +56 * Name of egg metatdata 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 key used in the properties file to reference the analyzer's enabled property. +156 * Returns the phase that the analyzer is intended to run in. 157 * -158 * @return the analyzer's enabled property setting key +158 * @return the phase that the analyzer is intended to run in. 159 */ 160 @Override -161 protected String getAnalyzerEnabledSettingKey() { -162 return Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED; +161 public AnalysisPhase getAnalysisPhase() { +162 return ANALYSIS_PHASE; 163 } 164 -165 @Override -166 protected void analyzeFileType(Dependency dependency, Engine engine) -167 throws AnalysisException { -168 if ("whl".equals(dependency.getFileExtension())) { -169 collectMetadataFromArchiveFormat(dependency, DIST_INFO_FILTER, -170 METADATA_FILTER); -171 } else if (EGG_OR_ZIP.matcher( -172 StringUtils.stripToEmpty(dependency.getFileExtension())) -173 .matches()) { -174 collectMetadataFromArchiveFormat(dependency, EGG_INFO_FILTER, -175 PKG_INFO_FILTER); -176 } else { -177 final File actualFile = dependency.getActualFile(); -178 final String name = actualFile.getName(); -179 final boolean metadata = METADATA.equals(name); -180 if (metadata || PKG_INFO.equals(name)) { -181 final File parent = actualFile.getParentFile(); -182 final String parentName = parent.getName(); -183 dependency.setDisplayFileName(parentName + "/" + name); -184 if (parent.isDirectory() -185 && (metadata && parentName.endsWith(".dist-info") -186 || parentName.endsWith(".egg-info") || "EGG-INFO" -187 .equals(parentName))) { -188 collectWheelMetadata(dependency, actualFile); -189 } -190 } -191 } -192 } -193 -194 /** -195 * Collects the meta data from an archive. -196 * -197 * @param dependency the archive being scanned -198 * @param folderFilter the filter to apply to the folder -199 * @param metadataFilter the filter to apply to the meta data -200 * @throws AnalysisException thrown when there is a problem analyzing the dependency -201 */ -202 private void collectMetadataFromArchiveFormat(Dependency dependency, -203 FilenameFilter folderFilter, FilenameFilter metadataFilter) -204 throws AnalysisException { -205 final File temp = getNextTempDirectory(); -206 LOGGER.fine(String.format("%s exists? %b", temp, temp.exists())); -207 try { -208 ExtractionUtil.extractFilesUsingFilter( -209 new File(dependency.getActualFilePath()), temp, -210 metadataFilter); -211 } catch (ExtractionException ex) { -212 throw new AnalysisException(ex); -213 } -214 -215 collectWheelMetadata( -216 dependency, -217 getMatchingFile(getMatchingFile(temp, folderFilter), -218 metadataFilter)); -219 } -220 -221 /** -222 * Makes sure a usable temporary directory is available. -223 * -224 * @throws Exception an AnalyzeException is thrown when the temp directory cannot be created -225 */ -226 @Override -227 protected void initializeFileTypeAnalyzer() throws Exception { -228 final File baseDir = Settings.getTempDirectory(); -229 tempFileLocation = File.createTempFile("check", "tmp", baseDir); -230 if (!tempFileLocation.delete()) { -231 final String msg = String.format( -232 "Unable to delete temporary file '%s'.", -233 tempFileLocation.getAbsolutePath()); -234 throw new AnalysisException(msg); -235 } -236 if (!tempFileLocation.mkdirs()) { -237 final String msg = String.format( -238 "Unable to create directory '%s'.", -239 tempFileLocation.getAbsolutePath()); -240 throw new AnalysisException(msg); -241 } -242 } -243 -244 /** -245 * Deletes any files extracted from the Wheel during analysis. -246 */ -247 @Override -248 public void close() { -249 if (tempFileLocation != null && tempFileLocation.exists()) { -250 LOGGER.log(Level.FINE, "Attempting to delete temporary files"); -251 final boolean success = FileUtils.delete(tempFileLocation); -252 if (!success) { -253 LOGGER.log(Level.WARNING, -254 "Failed to delete some temporary files, see the log for more details"); -255 } -256 } -257 } -258 -259 /** -260 * Gathers evidence from the METADATA file. -261 * -262 * @param dependency the dependency being analyzed -263 * @param file a reference to the manifest/properties file -264 * @throws AnalysisException thrown when there is an error -265 */ -266 private static void collectWheelMetadata(Dependency dependency, File file) -267 throws AnalysisException { -268 final InternetHeaders headers = getManifestProperties(file); -269 addPropertyToEvidence(headers, dependency.getVersionEvidence(), -270 "Version", Confidence.HIGHEST); -271 addPropertyToEvidence(headers, dependency.getProductEvidence(), "Name", -272 Confidence.HIGHEST); -273 final String url = headers.getHeader("Home-page", null); -274 final EvidenceCollection vendorEvidence = dependency -275 .getVendorEvidence(); -276 if (StringUtils.isNotBlank(url)) { -277 if (UrlStringUtils.isUrl(url)) { -278 vendorEvidence.addEvidence(METADATA, "vendor", url, -279 Confidence.MEDIUM); -280 } -281 } -282 addPropertyToEvidence(headers, vendorEvidence, "Author", Confidence.LOW); -283 final String summary = headers.getHeader("Summary", null); -284 if (StringUtils.isNotBlank(summary)) { -285 JarAnalyzer -286 .addDescription(dependency, summary, METADATA, "summary"); -287 } -288 } -289 -290 /** -291 * Adds a value to the evidence collection. -292 * -293 * @param headers the properties collection -294 * @param evidence the evidence collection to add the value -295 * @param property the property name -296 * @param confidence the confidence of the evidence -297 */ -298 private static void addPropertyToEvidence(InternetHeaders headers, -299 EvidenceCollection evidence, String property, Confidence confidence) { -300 final String value = headers.getHeader(property, null); -301 LOGGER.fine(String.format("Property: %s, Value: %s", property, value)); -302 if (StringUtils.isNotBlank(value)) { -303 evidence.addEvidence(METADATA, property, value, confidence); -304 } -305 } -306 -307 /** -308 * Returns a list of files that match the given filter, this does not recursively scan the directory. -309 * -310 * @param folder the folder to filter -311 * @param filter the filter to apply to the files in the directory -312 * @return the list of Files in the directory that match the provided filter -313 */ -314 private static File getMatchingFile(File folder, FilenameFilter filter) { -315 File result = null; -316 final File[] matches = folder.listFiles(filter); -317 if (null != matches && 1 == matches.length) { -318 result = matches[0]; -319 } -320 return result; -321 } -322 -323 /** -324 * Reads the manifest entries from the provided file. -325 * -326 * @param manifest the manifest -327 * @return the manifest entries -328 */ -329 private static InternetHeaders getManifestProperties(File manifest) { -330 final InternetHeaders result = new InternetHeaders(); -331 if (null == manifest) { -332 LOGGER.fine("Manifest file not found."); -333 } else { -334 try { -335 result.load(new AutoCloseInputStream(new BufferedInputStream( -336 new FileInputStream(manifest)))); -337 } catch (MessagingException e) { -338 LOGGER.log(Level.WARNING, e.getMessage(), e); -339 } catch (FileNotFoundException e) { -340 LOGGER.log(Level.WARNING, e.getMessage(), e); -341 } -342 } -343 return result; -344 } -345 -346 /** -347 * Retrieves the next temporary destingation directory for extracting an archive. -348 * -349 * @return a directory -350 * @throws AnalysisException thrown if unable to create temporary directory -351 */ -352 private File getNextTempDirectory() throws AnalysisException { -353 File directory; -354 -355 // getting an exception for some directories not being able to be -356 // created; might be because the directory already exists? -357 do { -358 dirCount += 1; -359 directory = new File(tempFileLocation, String.valueOf(dirCount)); -360 } while (directory.exists()); -361 if (!directory.mkdirs()) { -362 throw new AnalysisException(String.format( -363 "Unable to create temp directory '%s'.", -364 directory.getAbsolutePath())); -365 } -366 return directory; -367 } -368 } +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 * @throws AnalysisException thrown when there is an error +273 */ +274 private static void collectWheelMetadata(Dependency dependency, File file) +275 throws AnalysisException { +276 final InternetHeaders headers = getManifestProperties(file); +277 addPropertyToEvidence(headers, dependency.getVersionEvidence(), +278 "Version", Confidence.HIGHEST); +279 addPropertyToEvidence(headers, dependency.getProductEvidence(), "Name", +280 Confidence.HIGHEST); +281 final String url = headers.getHeader("Home-page", null); +282 final EvidenceCollection vendorEvidence = dependency +283 .getVendorEvidence(); +284 if (StringUtils.isNotBlank(url)) { +285 if (UrlStringUtils.isUrl(url)) { +286 vendorEvidence.addEvidence(METADATA, "vendor", url, +287 Confidence.MEDIUM); +288 } +289 } +290 addPropertyToEvidence(headers, vendorEvidence, "Author", Confidence.LOW); +291 final String summary = headers.getHeader("Summary", null); +292 if (StringUtils.isNotBlank(summary)) { +293 JarAnalyzer +294 .addDescription(dependency, summary, METADATA, "summary"); +295 } +296 } +297 +298 /** +299 * Adds a value to the evidence collection. +300 * +301 * @param headers the properties collection +302 * @param evidence the evidence collection to add the value +303 * @param property the property name +304 * @param confidence the confidence of the evidence +305 */ +306 private static void addPropertyToEvidence(InternetHeaders headers, +307 EvidenceCollection evidence, String property, Confidence confidence) { +308 final String value = headers.getHeader(property, null); +309 LOGGER.debug("Property: {}, Value: {}", property, value); +310 if (StringUtils.isNotBlank(value)) { +311 evidence.addEvidence(METADATA, property, value, confidence); +312 } +313 } +314 +315 /** +316 * Returns a list of files that match the given filter, this does not recursively scan the directory. +317 * +318 * @param folder the folder to filter +319 * @param filter the filter to apply to the files in the directory +320 * @return the list of Files in the directory that match the provided filter +321 */ +322 private static File getMatchingFile(File folder, FilenameFilter filter) { +323 File result = null; +324 final File[] matches = folder.listFiles(filter); +325 if (null != matches && 1 == matches.length) { +326 result = matches[0]; +327 } +328 return result; +329 } +330 +331 /** +332 * Reads the manifest entries from the provided file. +333 * +334 * @param manifest the manifest +335 * @return the manifest entries +336 */ +337 private static InternetHeaders getManifestProperties(File manifest) { +338 final InternetHeaders result = new InternetHeaders(); +339 if (null == manifest) { +340 LOGGER.debug("Manifest file not found."); +341 } else { +342 try { +343 result.load(new AutoCloseInputStream(new BufferedInputStream( +344 new FileInputStream(manifest)))); +345 } catch (MessagingException e) { +346 LOGGER.warn(e.getMessage(), e); +347 } catch (FileNotFoundException e) { +348 LOGGER.warn(e.getMessage(), e); +349 } +350 } +351 return result; +352 } +353 +354 /** +355 * Retrieves the next temporary destingation directory for extracting an archive. +356 * +357 * @return a directory +358 * @throws AnalysisException thrown if unable to create temporary directory +359 */ +360 private File getNextTempDirectory() throws AnalysisException { +361 File directory; +362 +363 // getting an exception for some directories not being able to be +364 // created; might be because the directory already exists? +365 do { +366 dirCount += 1; +367 directory = new File(tempFileLocation, String.valueOf(dirCount)); +368 } while (directory.exists()); +369 if (!directory.mkdirs()) { +370 throw new AnalysisException(String.format( +371 "Unable to create temp directory '%s'.", +372 directory.getAbsolutePath())); +373 } +374 return directory; +375 } +376 }
    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 c52700587..1f38ddcfb 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/PythonPackageAnalyzer.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/analyzer/PythonPackageAnalyzer.html @@ -25,28 +25,28 @@ 17 */ 18 package org.owasp.dependencycheck.analyzer; 19 -20 import java.io.File; -21 import java.io.FileFilter; -22 import java.io.IOException; -23 import java.net.MalformedURLException; -24 import java.util.ArrayList; -25 import java.util.Collections; -26 import java.util.List; -27 import java.util.Set; -28 import java.util.logging.Logger; -29 import java.util.regex.Matcher; -30 import java.util.regex.Pattern; -31 -32 import org.apache.commons.io.FileUtils; -33 import org.apache.commons.io.filefilter.NameFileFilter; -34 import org.apache.commons.io.filefilter.SuffixFileFilter; -35 import org.owasp.dependencycheck.Engine; -36 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; -37 import org.owasp.dependencycheck.dependency.Confidence; -38 import org.owasp.dependencycheck.dependency.Dependency; -39 import org.owasp.dependencycheck.dependency.EvidenceCollection; -40 import org.owasp.dependencycheck.utils.Settings; -41 import org.owasp.dependencycheck.utils.UrlStringUtils; +20 import org.apache.commons.io.FileUtils; +21 import org.apache.commons.io.filefilter.NameFileFilter; +22 import org.apache.commons.io.filefilter.SuffixFileFilter; +23 import org.owasp.dependencycheck.Engine; +24 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; +25 import org.owasp.dependencycheck.dependency.Confidence; +26 import org.owasp.dependencycheck.dependency.Dependency; +27 import org.owasp.dependencycheck.dependency.EvidenceCollection; +28 import org.owasp.dependencycheck.utils.FileFilterBuilder; +29 import org.owasp.dependencycheck.utils.Settings; +30 import org.owasp.dependencycheck.utils.UrlStringUtils; +31 import org.slf4j.Logger; +32 import org.slf4j.LoggerFactory; +33 +34 import java.io.File; +35 import java.io.FileFilter; +36 import java.io.IOException; +37 import java.net.MalformedURLException; +38 import java.util.ArrayList; +39 import java.util.List; +40 import java.util.regex.Matcher; +41 import java.util.regex.Pattern; 42 43 /** 44 * Used to analyze a Python package, and collect information that can be used to determine the associated CPE. @@ -64,271 +64,275 @@ 56 /** 57 * The logger. 58 */ -59 private static final Logger LOGGER = Logger -60 .getLogger(PythonDistributionAnalyzer.class.getName()); +59 private static final Logger LOGGER = LoggerFactory +60 .getLogger(PythonPackageAnalyzer.class); 61 62 /** 63 * Filename extensions for files to be analyzed. 64 */ -65 private static final Set<String> EXTENSIONS = Collections -66 .unmodifiableSet(Collections.singleton("py")); -67 -68 /** -69 * Pattern for matching the module docstring in a source file. -70 */ -71 private static final Pattern MODULE_DOCSTRING = Pattern.compile( -72 "^(['\\\"]{3})(.*?)\\1", REGEX_OPTIONS); -73 -74 /** -75 * Matches assignments to version variables in Python source code. -76 */ -77 private static final Pattern VERSION_PATTERN = Pattern.compile( -78 "\\b(__)?version(__)? *= *(['\"]+)(\\d+\\.\\d+.*?)\\3", -79 REGEX_OPTIONS); -80 -81 /** -82 * Matches assignments to title variables in Python source code. -83 */ -84 private static final Pattern TITLE_PATTERN = compileAssignPattern("title"); -85 -86 /** -87 * Matches assignments to summary variables in Python source code. -88 */ -89 private static final Pattern SUMMARY_PATTERN = compileAssignPattern("summary"); -90 -91 /** -92 * Matches assignments to URL/URL variables in Python source code. -93 */ -94 private static final Pattern URI_PATTERN = compileAssignPattern("ur[il]"); -95 -96 /** -97 * Matches assignments to home page variables in Python source code. -98 */ -99 private static final Pattern HOMEPAGE_PATTERN = compileAssignPattern("home_?page"); -100 -101 /** -102 * Matches assignments to author variables in Python source code. -103 */ -104 private static final Pattern AUTHOR_PATTERN = compileAssignPattern("author"); -105 -106 /** -107 * Filter that detects files named "__init__.py". -108 */ -109 private static final FileFilter INIT_PY_FILTER = new NameFileFilter("__init__.py"); -110 -111 /** -112 * The file filter for python files. -113 */ -114 private static final FileFilter PY_FILTER = new SuffixFileFilter(".py"); -115 -116 /** -117 * Returns the name of the Python Package Analyzer. -118 * -119 * @return the name of the analyzer -120 */ -121 @Override -122 public String getName() { -123 return "Python Package Analyzer"; -124 } -125 -126 /** -127 * Tell that we are used for information collection. -128 * -129 * @return INFORMATION_COLLECTION -130 */ -131 @Override -132 public AnalysisPhase getAnalysisPhase() { -133 return AnalysisPhase.INFORMATION_COLLECTION; -134 } -135 -136 /** -137 * Returns the set of supported file extensions. -138 * -139 * @return the set of supported file extensions -140 */ -141 @Override -142 protected Set<String> getSupportedExtensions() { -143 return EXTENSIONS; -144 } -145 -146 /** -147 * No-op initializer implementation. -148 * -149 * @throws Exception never thrown -150 */ -151 @Override -152 protected void initializeFileTypeAnalyzer() throws Exception { -153 // Nothing to do here. -154 } -155 -156 /** -157 * Utility function to create a regex pattern matcher. -158 * -159 * @param name the value to use when constructing the assignment pattern -160 * @return the compiled Pattern -161 */ -162 private static Pattern compileAssignPattern(String name) { -163 return Pattern.compile( -164 String.format("\\b(__)?%s(__)?\\b *= *(['\"]+)(.*?)\\3", name), -165 REGEX_OPTIONS); -166 } -167 -168 /** -169 * Analyzes python packages and adds evidence to the dependency. -170 * -171 * @param dependency the dependency being analyzed -172 * @param engine the engine being used to perform the scan -173 * @throws AnalysisException thrown if there is an unrecoverable error analyzing the dependency -174 */ -175 @Override -176 protected void analyzeFileType(Dependency dependency, Engine engine) -177 throws AnalysisException { -178 final File file = dependency.getActualFile(); -179 final File parent = file.getParentFile(); -180 final String parentName = parent.getName(); -181 boolean found = false; -182 if (INIT_PY_FILTER.accept(file)) { -183 for (final File sourcefile : parent.listFiles(PY_FILTER)) { -184 found |= analyzeFileContents(dependency, sourcefile); -185 } -186 } -187 if (found) { -188 dependency.setDisplayFileName(parentName + "/__init__.py"); -189 dependency.getProductEvidence().addEvidence(file.getName(), -190 "PackageName", parentName, Confidence.MEDIUM); -191 } else { -192 // copy, alter and set in case some other thread is iterating over -193 final List<Dependency> deps = new ArrayList<Dependency>( -194 engine.getDependencies()); -195 deps.remove(dependency); -196 engine.setDependencies(deps); -197 } -198 } -199 -200 /** -201 * This should gather information from leading docstrings, file comments, and assignments to __version__, __title__, -202 * __summary__, __uri__, __url__, __home*page__, __author__, and their all caps equivalents. -203 * -204 * @param dependency the dependency being analyzed -205 * @param file the file name to analyze -206 * @return whether evidence was found -207 * @throws AnalysisException thrown if there is an unrecoverable error -208 */ -209 private boolean analyzeFileContents(Dependency dependency, File file) -210 throws AnalysisException { -211 String contents = ""; -212 try { -213 contents = FileUtils.readFileToString(file).trim(); -214 } catch (IOException e) { -215 throw new AnalysisException( -216 "Problem occured while reading dependency file.", e); -217 } -218 boolean found = false; -219 if (!contents.isEmpty()) { -220 final String source = file.getName(); -221 found = gatherEvidence(VERSION_PATTERN, contents, source, -222 dependency.getVersionEvidence(), "SourceVersion", -223 Confidence.MEDIUM); -224 found |= addSummaryInfo(dependency, SUMMARY_PATTERN, 4, contents, -225 source, "summary"); -226 if (INIT_PY_FILTER.accept(file)) { -227 found |= addSummaryInfo(dependency, MODULE_DOCSTRING, 2, -228 contents, source, "docstring"); -229 } -230 found |= gatherEvidence(TITLE_PATTERN, contents, source, -231 dependency.getProductEvidence(), "SourceTitle", -232 Confidence.LOW); -233 final EvidenceCollection vendorEvidence = dependency -234 .getVendorEvidence(); -235 found |= gatherEvidence(AUTHOR_PATTERN, contents, source, -236 vendorEvidence, "SourceAuthor", Confidence.MEDIUM); -237 try { -238 found |= gatherHomePageEvidence(URI_PATTERN, vendorEvidence, -239 source, "URL", contents); -240 found |= gatherHomePageEvidence(HOMEPAGE_PATTERN, -241 vendorEvidence, source, "HomePage", contents); -242 } catch (MalformedURLException e) { -243 LOGGER.warning(e.getMessage()); -244 } -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 * @throws MalformedURLException thrown if the URL is malformed -281 */ -282 private boolean gatherHomePageEvidence(Pattern pattern, -283 EvidenceCollection evidence, String source, String name, -284 String contents) throws MalformedURLException { -285 final Matcher matcher = pattern.matcher(contents); -286 boolean found = false; -287 if (matcher.find()) { -288 final String url = matcher.group(4); -289 if (UrlStringUtils.isUrl(url)) { -290 found = true; -291 evidence.addEvidence(source, name, url, Confidence.MEDIUM); -292 } -293 } -294 return found; -295 } -296 -297 /** -298 * Gather evidence from a Python source file usin the given string 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 } +65 private static final String EXTENSIONS = "py"; +66 +67 /** +68 * Pattern for matching the module docstring in a source file. +69 */ +70 private static final Pattern MODULE_DOCSTRING = Pattern.compile( +71 "^(['\\\"]{3})(.*?)\\1", REGEX_OPTIONS); +72 +73 /** +74 * Matches assignments to version variables in Python source code. +75 */ +76 private static final Pattern VERSION_PATTERN = Pattern.compile( +77 "\\b(__)?version(__)? *= *(['\"]+)(\\d+\\.\\d+.*?)\\3", +78 REGEX_OPTIONS); +79 +80 /** +81 * Matches assignments to title variables in Python source code. +82 */ +83 private static final Pattern TITLE_PATTERN = compileAssignPattern("title"); +84 +85 /** +86 * Matches assignments to summary variables in Python source code. +87 */ +88 private static final Pattern SUMMARY_PATTERN = compileAssignPattern("summary"); +89 +90 /** +91 * Matches assignments to URL/URL variables in Python source code. +92 */ +93 private static final Pattern URI_PATTERN = compileAssignPattern("ur[il]"); +94 +95 /** +96 * Matches assignments to home page variables in Python source code. +97 */ +98 private static final Pattern HOMEPAGE_PATTERN = compileAssignPattern("home_?page"); +99 +100 /** +101 * Matches assignments to author variables in Python source code. +102 */ +103 private static final Pattern AUTHOR_PATTERN = compileAssignPattern("author"); +104 +105 /** +106 * Filter that detects files named "__init__.py". +107 */ +108 private static final FileFilter INIT_PY_FILTER = new NameFileFilter("__init__.py"); +109 +110 /** +111 * The file filter for python files. +112 */ +113 private static final FileFilter PY_FILTER = new SuffixFileFilter(".py"); +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 "Python Package 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 * The file filter used to determine which files this analyzer supports. +137 */ +138 private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions(EXTENSIONS).build(); +139 +140 /** +141 * Returns the FileFilter +142 * +143 * @return the FileFilter +144 */ +145 @Override +146 protected FileFilter getFileFilter() { +147 return FILTER; +148 } +149 +150 /** +151 * No-op initializer implementation. +152 * +153 * @throws Exception never thrown +154 */ +155 @Override +156 protected void initializeFileTypeAnalyzer() throws Exception { +157 // Nothing to do here. +158 } +159 +160 /** +161 * Utility function to create a regex pattern matcher. +162 * +163 * @param name the value to use when constructing the assignment pattern +164 * @return the compiled Pattern +165 */ +166 private static Pattern compileAssignPattern(String name) { +167 return Pattern.compile( +168 String.format("\\b(__)?%s(__)?\\b *= *(['\"]+)(.*?)\\3", name), +169 REGEX_OPTIONS); +170 } +171 +172 /** +173 * Analyzes python packages and adds evidence to the dependency. +174 * +175 * @param dependency the dependency being analyzed +176 * @param engine the engine being used to perform the scan +177 * @throws AnalysisException thrown if there is an unrecoverable error analyzing the dependency +178 */ +179 @Override +180 protected void analyzeFileType(Dependency dependency, Engine engine) +181 throws AnalysisException { +182 final File file = dependency.getActualFile(); +183 final File parent = file.getParentFile(); +184 final String parentName = parent.getName(); +185 boolean found = false; +186 if (INIT_PY_FILTER.accept(file)) { +187 for (final File sourcefile : parent.listFiles(PY_FILTER)) { +188 found |= analyzeFileContents(dependency, sourcefile); +189 } +190 } +191 if (found) { +192 dependency.setDisplayFileName(parentName + "/__init__.py"); +193 dependency.getProductEvidence().addEvidence(file.getName(), +194 "PackageName", parentName, Confidence.MEDIUM); +195 } else { +196 // copy, alter and set in case some other thread is iterating over +197 final List<Dependency> deps = new ArrayList<Dependency>( +198 engine.getDependencies()); +199 deps.remove(dependency); +200 engine.setDependencies(deps); +201 } +202 } +203 +204 /** +205 * This should gather information from leading docstrings, file comments, and assignments to __version__, __title__, +206 * __summary__, __uri__, __url__, __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).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 try { +242 found |= gatherHomePageEvidence(URI_PATTERN, vendorEvidence, +243 source, "URL", contents); +244 found |= gatherHomePageEvidence(HOMEPAGE_PATTERN, +245 vendorEvidence, source, "HomePage", contents); +246 } catch (MalformedURLException e) { +247 LOGGER.warn(e.getMessage()); +248 } +249 } +250 return found; +251 } +252 +253 /** +254 * Adds summary information to the dependency +255 * +256 * @param dependency the dependency being analyzed +257 * @param pattern the pattern used to perform analysis +258 * @param group the group from the pattern that indicates the data to use +259 * @param contents the data being analyzed +260 * @param source the source name to use when recording the evidence +261 * @param key the key name to use when recording the evidence +262 * @return true if evidence was collected; otherwise false +263 */ +264 private boolean addSummaryInfo(Dependency dependency, Pattern pattern, +265 int group, String contents, String source, String key) { +266 final Matcher matcher = pattern.matcher(contents); +267 final boolean found = matcher.find(); +268 if (found) { +269 JarAnalyzer.addDescription(dependency, matcher.group(group), +270 source, key); +271 } +272 return found; +273 } +274 +275 /** +276 * Collects evidence from the home page URL. +277 * +278 * @param pattern the pattern to match +279 * @param evidence the evidence collection to add the evidence to +280 * @param source the source of the evidence +281 * @param name the name of the evidence +282 * @param contents the home page URL +283 * @return true if evidence was collected; otherwise false +284 * @throws MalformedURLException thrown if the URL is malformed +285 */ +286 private boolean gatherHomePageEvidence(Pattern pattern, +287 EvidenceCollection evidence, String source, String name, +288 String contents) throws MalformedURLException { +289 final Matcher matcher = pattern.matcher(contents); +290 boolean found = false; +291 if (matcher.find()) { +292 final String url = matcher.group(4); +293 if (UrlStringUtils.isUrl(url)) { +294 found = true; +295 evidence.addEvidence(source, name, url, Confidence.MEDIUM); +296 } +297 } +298 return found; +299 } +300 +301 /** +302 * Gather evidence from a Python source file usin the given string assignment regex pattern. +303 * +304 * @param pattern to scan contents with +305 * @param contents of Python source file +306 * @param source for storing evidence +307 * @param evidence to store evidence in +308 * @param name of evidence +309 * @param confidence in evidence +310 * @return whether evidence was found +311 */ +312 private boolean gatherEvidence(Pattern pattern, String contents, +313 String source, EvidenceCollection evidence, String name, +314 Confidence confidence) { +315 final Matcher matcher = pattern.matcher(contents); +316 final boolean found = matcher.find(); +317 if (found) { +318 evidence.addEvidence(source, name, matcher.group(4), confidence); +319 } +320 return found; +321 } +322 +323 @Override +324 protected String getAnalyzerEnabledSettingKey() { +325 return Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED; +326 } +327 }
    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 d6af27e17..780586f3c 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.2.11 Reference Package org.owasp.dependencycheck.analyzer.exception + Dependency-Check Core 1.3.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 b36648dae..86316bb8d 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.2.11 Reference Package org.owasp.dependencycheck.analyzer.exception + Dependency-Check Core 1.3.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 d6b643de2..78ee96294 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.2.11 Reference Package org.owasp.dependencycheck.analyzer + Dependency-Check Core 1.3.0 Reference Package org.owasp.dependencycheck.analyzer @@ -38,6 +38,12 @@
  • AssemblyAnalyzer +
  • +
  • + AutoconfAnalyzer +
  • +
  • + CMakeAnalyzer
  • CPEAnalyzer @@ -74,9 +80,6 @@
  • JarAnalyzer -
  • -
  • - JavaScriptAnalyzer
  • NexusAnalyzer @@ -86,6 +89,9 @@
  • NvdCveAnalyzer +
  • +
  • + OpenSSLAnalyzer
  • PythonDistributionAnalyzer 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 78f665a38..9a12c13d0 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.2.11 Reference Package org.owasp.dependencycheck.analyzer + Dependency-Check Core 1.3.0 Reference Package org.owasp.dependencycheck.analyzer @@ -74,6 +74,16 @@
  • + + + + + + - - - + + + + + + + + + - - - - - - - - -
    - org.owasp.dependencycheck.data.update.task -
    - org.owasp.dependencycheck.data.update.xml + org.owasp.dependencycheck.data.update.nvd
    AssemblyAnalyzer
    + AutoconfAnalyzer +
    + CMakeAnalyzer +
    @@ -134,11 +144,6 @@ JarAnalyzer
    - JavaScriptAnalyzer -
    @@ -154,6 +159,11 @@ NvdCveAnalyzer
    + OpenSSLAnalyzer +
    diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/central/CentralSearch.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/central/CentralSearch.html index db274471b..012021f32 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/central/CentralSearch.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/central/CentralSearch.html @@ -31,147 +31,147 @@ 23 import java.net.URL; 24 import java.util.ArrayList; 25 import java.util.List; -26 import java.util.logging.Logger; -27 import javax.xml.parsers.DocumentBuilder; -28 import javax.xml.parsers.DocumentBuilderFactory; -29 import javax.xml.xpath.XPath; -30 import javax.xml.xpath.XPathConstants; -31 import javax.xml.xpath.XPathFactory; -32 import org.owasp.dependencycheck.data.nexus.MavenArtifact; -33 import org.owasp.dependencycheck.utils.Settings; -34 import org.owasp.dependencycheck.utils.URLConnectionFactory; -35 import org.w3c.dom.Document; -36 import org.w3c.dom.NodeList; -37 -38 /** -39 * Class of methods to search Maven Central via Central. -40 * -41 * @author colezlaw -42 */ -43 public class CentralSearch { -44 -45 /** -46 * The URL for the Central service -47 */ -48 private final URL rootURL; -49 -50 /** -51 * Whether to use the Proxy when making requests -52 */ -53 private boolean useProxy; -54 -55 /** -56 * Used for logging. -57 */ -58 private static final Logger LOGGER = Logger.getLogger(CentralSearch.class.getName()); -59 -60 /** -61 * Creates a NexusSearch for the given repository URL. -62 * -63 * @param rootURL the URL of the repository on which searches should execute. Only parameters are added to this (so it should -64 * end in /select) -65 */ -66 public CentralSearch(URL rootURL) { -67 this.rootURL = rootURL; -68 if (null != Settings.getString(Settings.KEYS.PROXY_SERVER)) { -69 useProxy = true; -70 LOGGER.fine("Using proxy"); -71 } else { -72 useProxy = false; -73 LOGGER.fine("Not using proxy"); -74 } -75 } -76 -77 /** -78 * Searches the configured Central URL for the given sha1 hash. If the artifact is found, a <code>MavenArtifact</code> is -79 * populated with the GAV. -80 * -81 * @param sha1 the SHA-1 hash string for which to search -82 * @return the populated Maven GAV. -83 * @throws IOException if it's unable to connect to the specified repository or if the specified artifact is not found. -84 */ -85 public List<MavenArtifact> searchSha1(String sha1) throws IOException { -86 if (null == sha1 || !sha1.matches("^[0-9A-Fa-f]{40}$")) { -87 throw new IllegalArgumentException("Invalid SHA1 format"); -88 } -89 -90 final URL url = new URL(rootURL + String.format("?q=1:\"%s\"&wt=xml", sha1)); -91 -92 LOGGER.fine(String.format("Searching Central url %s", url.toString())); -93 -94 // Determine if we need to use a proxy. The rules: -95 // 1) If the proxy is set, AND the setting is set to true, use the proxy -96 // 2) Otherwise, don't use the proxy (either the proxy isn't configured, -97 // or proxy is specifically set to false) -98 final HttpURLConnection conn = URLConnectionFactory.createHttpURLConnection(url, useProxy); -99 -100 conn.setDoOutput(true); -101 -102 // JSON would be more elegant, but there's not currently a dependency -103 // on JSON, so don't want to add one just for this -104 conn.addRequestProperty("Accept", "application/xml"); -105 conn.connect(); -106 -107 if (conn.getResponseCode() == 200) { -108 boolean missing = false; -109 try { -110 final DocumentBuilder builder = DocumentBuilderFactory -111 .newInstance().newDocumentBuilder(); -112 final Document doc = builder.parse(conn.getInputStream()); -113 final XPath xpath = XPathFactory.newInstance().newXPath(); -114 final String numFound = xpath.evaluate("/response/result/@numFound", doc); -115 if ("0".equals(numFound)) { -116 missing = true; -117 } else { -118 final ArrayList<MavenArtifact> result = new ArrayList<MavenArtifact>(); -119 final NodeList docs = (NodeList) xpath.evaluate("/response/result/doc", doc, XPathConstants.NODESET); -120 for (int i = 0; i < docs.getLength(); i++) { -121 final String g = xpath.evaluate("./str[@name='g']", docs.item(i)); -122 LOGGER.finest(String.format("GroupId: %s", g)); -123 final String a = xpath.evaluate("./str[@name='a']", docs.item(i)); -124 LOGGER.finest(String.format("ArtifactId: %s", a)); -125 final String v = xpath.evaluate("./str[@name='v']", docs.item(i)); -126 NodeList atts = (NodeList) xpath.evaluate("./arr[@name='ec']/str", docs.item(i), XPathConstants.NODESET); -127 boolean pomAvailable = false; -128 boolean jarAvailable = false; -129 for (int x = 0; x < atts.getLength(); x++) { -130 final String tmp = xpath.evaluate(".", atts.item(x)); -131 if (".pom".equals(tmp)) { -132 pomAvailable = true; -133 } else if (".jar".equals(tmp)) { -134 jarAvailable = true; -135 } -136 } -137 -138 atts = (NodeList) xpath.evaluate("./arr[@name='tags']/str", docs.item(i), XPathConstants.NODESET); -139 boolean useHTTPS = false; -140 for (int x = 0; x < atts.getLength(); x++) { -141 final String tmp = xpath.evaluate(".", atts.item(x)); -142 if ("https".equals(tmp)) { -143 useHTTPS = true; -144 } -145 } -146 -147 LOGGER.finest(String.format("Version: %s", v)); -148 result.add(new MavenArtifact(g, a, v, jarAvailable, pomAvailable, useHTTPS)); -149 } -150 -151 return result; -152 } -153 } catch (Throwable e) { -154 // Anything else is jacked up XML stuff that we really can't recover -155 // from well -156 throw new IOException(e.getMessage(), e); -157 } -158 -159 if (missing) { -160 throw new FileNotFoundException("Artifact not found in Central"); -161 } -162 } else { -163 final String msg = String.format("Could not connect to Central received response code: %d %s", -164 conn.getResponseCode(), conn.getResponseMessage()); -165 LOGGER.fine(msg); -166 throw new IOException(msg); +26 import javax.xml.parsers.DocumentBuilder; +27 import javax.xml.parsers.DocumentBuilderFactory; +28 import javax.xml.xpath.XPath; +29 import javax.xml.xpath.XPathConstants; +30 import javax.xml.xpath.XPathFactory; +31 import org.owasp.dependencycheck.data.nexus.MavenArtifact; +32 import org.owasp.dependencycheck.utils.Settings; +33 import org.owasp.dependencycheck.utils.URLConnectionFactory; +34 import org.slf4j.Logger; +35 import org.slf4j.LoggerFactory; +36 import org.w3c.dom.Document; +37 import org.w3c.dom.NodeList; +38 +39 /** +40 * Class of methods to search Maven Central via Central. +41 * +42 * @author colezlaw +43 */ +44 public class CentralSearch { +45 +46 /** +47 * The URL for the Central service +48 */ +49 private final URL rootURL; +50 +51 /** +52 * Whether to use the Proxy when making requests +53 */ +54 private boolean useProxy; +55 +56 /** +57 * Used for logging. +58 */ +59 private static final Logger LOGGER = LoggerFactory.getLogger(CentralSearch.class); +60 +61 /** +62 * Creates a NexusSearch for the given repository URL. +63 * +64 * @param rootURL the URL of the repository on which searches should execute. Only parameters are added to this (so it should +65 * end in /select) +66 */ +67 public CentralSearch(URL rootURL) { +68 this.rootURL = rootURL; +69 if (null != Settings.getString(Settings.KEYS.PROXY_SERVER)) { +70 useProxy = true; +71 LOGGER.debug("Using proxy"); +72 } else { +73 useProxy = false; +74 LOGGER.debug("Not using proxy"); +75 } +76 } +77 +78 /** +79 * Searches the configured Central URL for the given sha1 hash. If the artifact is found, a <code>MavenArtifact</code> is +80 * populated with the GAV. +81 * +82 * @param sha1 the SHA-1 hash string for which to search +83 * @return the populated Maven GAV. +84 * @throws IOException if it's unable to connect to the specified repository or if the specified artifact is not found. +85 */ +86 public List<MavenArtifact> searchSha1(String sha1) throws IOException { +87 if (null == sha1 || !sha1.matches("^[0-9A-Fa-f]{40}$")) { +88 throw new IllegalArgumentException("Invalid SHA1 format"); +89 } +90 +91 final URL url = new URL(rootURL + String.format("?q=1:\"%s\"&wt=xml", sha1)); +92 +93 LOGGER.debug("Searching Central url {}", url.toString()); +94 +95 // Determine if we need to use a proxy. The rules: +96 // 1) If the proxy is set, AND the setting is set to true, use the proxy +97 // 2) Otherwise, don't use the proxy (either the proxy isn't configured, +98 // or proxy is specifically set to false) +99 final HttpURLConnection conn = URLConnectionFactory.createHttpURLConnection(url, useProxy); +100 +101 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 conn.addRequestProperty("Accept", "application/xml"); +106 conn.connect(); +107 +108 if (conn.getResponseCode() == 200) { +109 boolean missing = false; +110 try { +111 final DocumentBuilder builder = DocumentBuilderFactory +112 .newInstance().newDocumentBuilder(); +113 final Document doc = builder.parse(conn.getInputStream()); +114 final XPath xpath = XPathFactory.newInstance().newXPath(); +115 final String numFound = xpath.evaluate("/response/result/@numFound", doc); +116 if ("0".equals(numFound)) { +117 missing = true; +118 } else { +119 final ArrayList<MavenArtifact> result = new ArrayList<MavenArtifact>(); +120 final NodeList docs = (NodeList) xpath.evaluate("/response/result/doc", doc, XPathConstants.NODESET); +121 for (int i = 0; i < docs.getLength(); i++) { +122 final String g = xpath.evaluate("./str[@name='g']", docs.item(i)); +123 LOGGER.trace("GroupId: {}", g); +124 final String a = xpath.evaluate("./str[@name='a']", docs.item(i)); +125 LOGGER.trace("ArtifactId: {}", a); +126 final String v = xpath.evaluate("./str[@name='v']", docs.item(i)); +127 NodeList atts = (NodeList) xpath.evaluate("./arr[@name='ec']/str", docs.item(i), XPathConstants.NODESET); +128 boolean pomAvailable = false; +129 boolean jarAvailable = false; +130 for (int x = 0; x < atts.getLength(); x++) { +131 final String tmp = xpath.evaluate(".", atts.item(x)); +132 if (".pom".equals(tmp)) { +133 pomAvailable = true; +134 } else if (".jar".equals(tmp)) { +135 jarAvailable = true; +136 } +137 } +138 +139 atts = (NodeList) xpath.evaluate("./arr[@name='tags']/str", docs.item(i), XPathConstants.NODESET); +140 boolean useHTTPS = false; +141 for (int x = 0; x < atts.getLength(); x++) { +142 final String tmp = xpath.evaluate(".", atts.item(x)); +143 if ("https".equals(tmp)) { +144 useHTTPS = true; +145 } +146 } +147 +148 LOGGER.trace("Version: {}", v); +149 result.add(new MavenArtifact(g, a, v, jarAvailable, pomAvailable, useHTTPS)); +150 } +151 +152 return result; +153 } +154 } catch (Throwable e) { +155 // Anything else is jacked up XML stuff that we really can't recover +156 // from well +157 throw new IOException(e.getMessage(), e); +158 } +159 +160 if (missing) { +161 throw new FileNotFoundException("Artifact not found in Central"); +162 } +163 } else { +164 LOGGER.debug("Could not connect to Central received response code: {} {}", +165 conn.getResponseCode(), conn.getResponseMessage()); +166 throw new IOException("Could not connect to Central"); 167 } 168 169 return null; 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 20d61102a..f678d11ec 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.2.11 Reference Package org.owasp.dependencycheck.data.central + Dependency-Check Core 1.3.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 9908fd8b5..4c66571fc 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.2.11 Reference Package org.owasp.dependencycheck.data.central + Dependency-Check Core 1.3.0 Reference Package org.owasp.dependencycheck.data.central diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/cpe/CpeMemoryIndex.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/cpe/CpeMemoryIndex.html index cfcac958f..bca23f0ac 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/cpe/CpeMemoryIndex.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/cpe/CpeMemoryIndex.html @@ -29,31 +29,31 @@ 21 import java.util.HashMap; 22 import java.util.Map; 23 import java.util.Set; -24 import java.util.logging.Level; -25 import java.util.logging.Logger; -26 import org.apache.lucene.analysis.Analyzer; -27 import org.apache.lucene.analysis.core.KeywordAnalyzer; -28 import org.apache.lucene.analysis.miscellaneous.PerFieldAnalyzerWrapper; -29 import org.apache.lucene.document.Document; -30 import org.apache.lucene.document.Field; -31 import org.apache.lucene.document.TextField; -32 import org.apache.lucene.index.CorruptIndexException; -33 import org.apache.lucene.index.DirectoryReader; -34 import org.apache.lucene.index.IndexReader; -35 import org.apache.lucene.index.IndexWriter; -36 import org.apache.lucene.index.IndexWriterConfig; -37 import org.apache.lucene.queryparser.classic.ParseException; -38 import org.apache.lucene.queryparser.classic.QueryParser; -39 import org.apache.lucene.search.IndexSearcher; -40 import org.apache.lucene.search.Query; -41 import org.apache.lucene.search.TopDocs; -42 import org.apache.lucene.store.RAMDirectory; -43 import org.owasp.dependencycheck.data.lucene.FieldAnalyzer; -44 import org.owasp.dependencycheck.data.lucene.LuceneUtils; -45 import org.owasp.dependencycheck.data.lucene.SearchFieldAnalyzer; -46 import org.owasp.dependencycheck.data.nvdcve.CveDB; -47 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; -48 import org.owasp.dependencycheck.utils.Pair; +24 import org.apache.lucene.analysis.Analyzer; +25 import org.apache.lucene.analysis.core.KeywordAnalyzer; +26 import org.apache.lucene.analysis.miscellaneous.PerFieldAnalyzerWrapper; +27 import org.apache.lucene.document.Document; +28 import org.apache.lucene.document.Field; +29 import org.apache.lucene.document.TextField; +30 import org.apache.lucene.index.CorruptIndexException; +31 import org.apache.lucene.index.DirectoryReader; +32 import org.apache.lucene.index.IndexReader; +33 import org.apache.lucene.index.IndexWriter; +34 import org.apache.lucene.index.IndexWriterConfig; +35 import org.apache.lucene.queryparser.classic.ParseException; +36 import org.apache.lucene.queryparser.classic.QueryParser; +37 import org.apache.lucene.search.IndexSearcher; +38 import org.apache.lucene.search.Query; +39 import org.apache.lucene.search.TopDocs; +40 import org.apache.lucene.store.RAMDirectory; +41 import org.owasp.dependencycheck.data.lucene.FieldAnalyzer; +42 import org.owasp.dependencycheck.data.lucene.LuceneUtils; +43 import org.owasp.dependencycheck.data.lucene.SearchFieldAnalyzer; +44 import org.owasp.dependencycheck.data.nvdcve.CveDB; +45 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; +46 import org.owasp.dependencycheck.utils.Pair; +47 import org.slf4j.Logger; +48 import org.slf4j.LoggerFactory; 49 50 /** 51 * An in memory lucene index that contains the vendor/product combinations from the CPE (application) identifiers within the NVD @@ -66,7 +66,7 @@ 58 /** 59 * The logger. 60 */ -61 private static final Logger LOGGER = Logger.getLogger(CpeMemoryIndex.class.getName()); +61 private static final Logger LOGGER = LoggerFactory.getLogger(CpeMemoryIndex.class); 62 /** 63 * singleton instance. 64 */ @@ -211,7 +211,7 @@ 203 try { 204 indexReader.close(); 205 } catch (IOException ex) { -206 LOGGER.log(Level.FINEST, null, ex); +206 LOGGER.trace("", ex); 207 } 208 indexReader = null; 209 } @@ -243,7 +243,7 @@ 235 saveEntry(pair.getLeft(), pair.getRight(), indexWriter); 236 } 237 } catch (DatabaseException ex) { -238 LOGGER.log(Level.FINE, null, ex); +238 LOGGER.debug("", ex); 239 throw new IndexException("Error reading CPE data", ex); 240 } 241 } catch (CorruptIndexException ex) { 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 798ed8e12..18ef3ead7 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.2.11 Reference Package org.owasp.dependencycheck.data.cpe + Dependency-Check Core 1.3.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 d8e7ec97f..870643cbe 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.2.11 Reference Package org.owasp.dependencycheck.data.cpe + Dependency-Check Core 1.3.0 Reference Package org.owasp.dependencycheck.data.cpe diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/cwe/CweDB.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/cwe/CweDB.html index e0a27ac4e..4b95575dc 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/cwe/CweDB.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/cwe/CweDB.html @@ -25,81 +25,82 @@ 17 */ 18 package org.owasp.dependencycheck.data.cwe; 19 -20 import java.io.IOException; -21 import java.io.InputStream; -22 import java.io.ObjectInputStream; -23 import java.util.HashMap; -24 import java.util.logging.Level; -25 import java.util.logging.Logger; -26 -27 /** -28 * -29 * @author Jeremy Long -30 */ -31 public final class CweDB { -32 -33 /** -34 * The Logger. -35 */ -36 private static final Logger LOGGER = Logger.getLogger(CweDB.class.getName()); -37 -38 /** -39 * Empty private constructor as this is a utility class. -40 */ -41 private CweDB() { -42 //empty -43 } -44 /** -45 * A HashMap of the CWE data. -46 */ -47 private static final HashMap<String, String> CWE = loadData(); -48 -49 /** -50 * Loads a HashMap containing the CWE data from a resource found in the jar. -51 * -52 * @return a HashMap of CWE data -53 */ -54 private static HashMap<String, String> loadData() { -55 ObjectInputStream oin = null; -56 try { -57 final String filePath = "data/cwe.hashmap.serialized"; -58 final InputStream input = CweDB.class.getClassLoader().getResourceAsStream(filePath); -59 oin = new ObjectInputStream(input); -60 @SuppressWarnings("unchecked") -61 final HashMap<String, String> ret = (HashMap<String, String>) oin.readObject(); -62 return ret; -63 } catch (ClassNotFoundException ex) { -64 LOGGER.log(Level.WARNING, "Unable to load CWE data. This should not be an issue."); -65 LOGGER.log(Level.FINE, null, ex); -66 } catch (IOException ex) { -67 LOGGER.log(Level.WARNING, "Unable to load CWE data due to an IO Error. This should not be an issue."); -68 LOGGER.log(Level.FINE, null, ex); -69 } finally { -70 if (oin != null) { -71 try { -72 oin.close(); -73 } catch (IOException ex) { -74 LOGGER.log(Level.FINEST, null, ex); -75 } -76 } -77 } -78 return null; -79 } -80 -81 /** -82 * <p> -83 * Returns the full CWE name from the CWE ID.</p> -84 * -85 * @param cweId the CWE ID -86 * @return the full name of the CWE -87 */ -88 public static String getCweName(String cweId) { -89 if (cweId != null) { -90 return CWE.get(cweId); -91 } -92 return null; -93 } -94 } +20 import org.slf4j.Logger; +21 import org.slf4j.LoggerFactory; +22 +23 import java.io.IOException; +24 import java.io.InputStream; +25 import java.io.ObjectInputStream; +26 import java.util.HashMap; +27 +28 /** +29 * +30 * @author Jeremy Long +31 */ +32 public final class CweDB { +33 +34 /** +35 * The Logger. +36 */ +37 private static final Logger LOGGER = LoggerFactory.getLogger(CweDB.class); +38 +39 /** +40 * Empty private constructor as this is a utility class. +41 */ +42 private CweDB() { +43 //empty +44 } +45 /** +46 * A HashMap of the CWE data. +47 */ +48 private static final HashMap<String, String> CWE = loadData(); +49 +50 /** +51 * Loads a HashMap containing the CWE data from a resource found in the jar. +52 * +53 * @return a HashMap of CWE data +54 */ +55 private static HashMap<String, String> loadData() { +56 ObjectInputStream oin = null; +57 try { +58 final String filePath = "data/cwe.hashmap.serialized"; +59 final InputStream input = CweDB.class.getClassLoader().getResourceAsStream(filePath); +60 oin = new ObjectInputStream(input); +61 @SuppressWarnings("unchecked") +62 final HashMap<String, String> ret = (HashMap<String, String>) oin.readObject(); +63 return ret; +64 } catch (ClassNotFoundException ex) { +65 LOGGER.warn("Unable to load CWE data. This should not be an issue."); +66 LOGGER.debug("", ex); +67 } catch (IOException ex) { +68 LOGGER.warn("Unable to load CWE data due to an IO Error. This should not be an issue."); +69 LOGGER.debug("", ex); +70 } finally { +71 if (oin != null) { +72 try { +73 oin.close(); +74 } catch (IOException ex) { +75 LOGGER.trace("", ex); +76 } +77 } +78 } +79 return null; +80 } +81 +82 /** +83 * <p> +84 * Returns the full CWE name from the CWE ID.</p> +85 * +86 * @param cweId the CWE ID +87 * @return the full name of the CWE +88 */ +89 public static String getCweName(String cweId) { +90 if (cweId != null) { +91 return CWE.get(cweId); +92 } +93 return null; +94 } +95 }
    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 5c31a80e7..23f3f85f7 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.2.11 Reference Package org.owasp.dependencycheck.data.cwe + Dependency-Check Core 1.3.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 d845808bb..9657f212d 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.2.11 Reference Package org.owasp.dependencycheck.data.cwe + Dependency-Check Core 1.3.0 Reference Package org.owasp.dependencycheck.data.cwe diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/lucene/UrlTokenizingFilter.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/lucene/UrlTokenizingFilter.html index 3db7f2bdc..74046a82a 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/lucene/UrlTokenizingFilter.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/lucene/UrlTokenizingFilter.html @@ -29,11 +29,11 @@ 21 import java.net.MalformedURLException; 22 import java.util.LinkedList; 23 import java.util.List; -24 import java.util.logging.Level; -25 import java.util.logging.Logger; -26 import org.apache.lucene.analysis.TokenStream; -27 import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; -28 import org.owasp.dependencycheck.utils.UrlStringUtils; +24 import org.apache.lucene.analysis.TokenStream; +25 import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; +26 import org.owasp.dependencycheck.utils.UrlStringUtils; +27 import org.slf4j.Logger; +28 import org.slf4j.LoggerFactory; 29 30 /** 31 * <p> @@ -47,7 +47,7 @@ 39 /** 40 * The logger. 41 */ -42 private static final Logger LOGGER = Logger.getLogger(UrlTokenizingFilter.class.getName()); +42 private static final Logger LOGGER = LoggerFactory.getLogger(UrlTokenizingFilter.class); 43 /** 44 * Constructs a new VersionTokenizingFilter. 45 * @@ -78,7 +78,7 @@ 70 final List<String> data = UrlStringUtils.extractImportantUrlData(part); 71 tokens.addAll(data); 72 } catch (MalformedURLException ex) { -73 LOGGER.log(Level.FINE, "error parsing " + part, ex); +73 LOGGER.debug("error parsing {}", part, ex); 74 tokens.add(part); 75 } 76 } else { 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 a65bf61b0..44f680420 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.2.11 Reference Package org.owasp.dependencycheck.data.lucene + Dependency-Check Core 1.3.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 dea8597a9..c42d664fe 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.2.11 Reference Package org.owasp.dependencycheck.data.lucene + Dependency-Check Core 1.3.0 Reference Package org.owasp.dependencycheck.data.lucene diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/nexus/NexusSearch.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/nexus/NexusSearch.html index 0f23c39ee..15a730e0e 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/nexus/NexusSearch.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/nexus/NexusSearch.html @@ -29,15 +29,15 @@ 21 import java.io.IOException; 22 import java.net.HttpURLConnection; 23 import java.net.URL; -24 import java.util.logging.Level; -25 import java.util.logging.Logger; -26 import javax.xml.parsers.DocumentBuilder; -27 import javax.xml.parsers.DocumentBuilderFactory; -28 import javax.xml.xpath.XPath; -29 import javax.xml.xpath.XPathFactory; -30 import org.owasp.dependencycheck.utils.InvalidSettingException; -31 import org.owasp.dependencycheck.utils.Settings; -32 import org.owasp.dependencycheck.utils.URLConnectionFactory; +24 import javax.xml.parsers.DocumentBuilder; +25 import javax.xml.parsers.DocumentBuilderFactory; +26 import javax.xml.xpath.XPath; +27 import javax.xml.xpath.XPathFactory; +28 import org.owasp.dependencycheck.utils.InvalidSettingException; +29 import org.owasp.dependencycheck.utils.Settings; +30 import org.owasp.dependencycheck.utils.URLConnectionFactory; +31 import org.slf4j.Logger; +32 import org.slf4j.LoggerFactory; 33 import org.w3c.dom.Document; 34 35 /** @@ -57,150 +57,141 @@ 49 */ 50 private boolean useProxy; 51 /** -52 * The username to use if the Nexus requires authentication. +52 * Used for logging. 53 */ -54 private String userName = null; -55 /** -56 * The password to use if the Nexus requires authentication. -57 */ -58 private char[] password; -59 /** -60 * Used for logging. +54 private static final Logger LOGGER = LoggerFactory.getLogger(NexusSearch.class); +55 +56 /** +57 * Creates a NexusSearch for the given repository URL. +58 * +59 * @param rootURL the root URL of the repository on which searches should execute. full URL's are calculated relative to this +60 * URL, so it should end with a / 61 */ -62 private static final Logger LOGGER = Logger.getLogger(NexusSearch.class.getName()); -63 -64 /** -65 * Creates a NexusSearch for the given repository URL. -66 * -67 * @param rootURL the root URL of the repository on which searches should execute. full URL's are calculated relative to this -68 * URL, so it should end with a / -69 */ -70 public NexusSearch(URL rootURL) { -71 this.rootURL = rootURL; -72 try { -73 if (null != Settings.getString(Settings.KEYS.PROXY_SERVER) -74 && Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_PROXY)) { -75 useProxy = true; -76 LOGGER.fine("Using proxy"); -77 } else { -78 useProxy = false; -79 LOGGER.fine("Not using proxy"); -80 } -81 } catch (InvalidSettingException ise) { -82 useProxy = false; -83 } -84 } -85 -86 /** -87 * Searches the configured Nexus repository for the given sha1 hash. If the artifact is found, a <code>MavenArtifact</code> is -88 * populated with the coordinate information. -89 * -90 * @param sha1 The SHA-1 hash string for which to search -91 * @return the populated Maven coordinates -92 * @throws IOException if it's unable to connect to the specified repository or if the specified artifact is not found. -93 */ -94 public MavenArtifact searchSha1(String sha1) throws IOException { -95 if (null == sha1 || !sha1.matches("^[0-9A-Fa-f]{40}$")) { -96 throw new IllegalArgumentException("Invalid SHA1 format"); -97 } -98 -99 final URL url = new URL(rootURL, String.format("identify/sha1/%s", -100 sha1.toLowerCase())); -101 -102 LOGGER.fine(String.format("Searching Nexus url %s", url.toString())); +62 public NexusSearch(URL rootURL) { +63 this.rootURL = rootURL; +64 try { +65 if (null != Settings.getString(Settings.KEYS.PROXY_SERVER) +66 && Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_PROXY)) { +67 useProxy = true; +68 LOGGER.debug("Using proxy"); +69 } else { +70 useProxy = false; +71 LOGGER.debug("Not using proxy"); +72 } +73 } catch (InvalidSettingException ise) { +74 useProxy = false; +75 } +76 } +77 +78 /** +79 * Searches the configured Nexus repository for the given sha1 hash. If the artifact is found, a <code>MavenArtifact</code> is +80 * populated with the coordinate information. +81 * +82 * @param sha1 The SHA-1 hash string for which to search +83 * @return the populated Maven coordinates +84 * @throws IOException if it's unable to connect to the specified repository or if the specified artifact is not found. +85 */ +86 public MavenArtifact searchSha1(String sha1) throws IOException { +87 if (null == sha1 || !sha1.matches("^[0-9A-Fa-f]{40}$")) { +88 throw new IllegalArgumentException("Invalid SHA1 format"); +89 } +90 +91 final URL url = new URL(rootURL, String.format("identify/sha1/%s", +92 sha1.toLowerCase())); +93 +94 LOGGER.debug("Searching Nexus url {}", url); +95 +96 // Determine if we need to use a proxy. The rules: +97 // 1) If the proxy is set, AND the setting is set to true, use the proxy +98 // 2) Otherwise, don't use the proxy (either the proxy isn't configured, +99 // or proxy is specifically set to false +100 HttpURLConnection conn; +101 conn = URLConnectionFactory.createHttpURLConnection(url, useProxy); +102 conn.setDoOutput(true); 103 -104 // Determine if we need to use a proxy. The rules: -105 // 1) If the proxy is set, AND the setting is set to true, use the proxy -106 // 2) Otherwise, don't use the proxy (either the proxy isn't configured, -107 // or proxy is specifically set to false -108 HttpURLConnection conn; -109 conn = URLConnectionFactory.createHttpURLConnection(url, useProxy); -110 conn.setDoOutput(true); -111 -112 // JSON would be more elegant, but there's not currently a dependency -113 // on JSON, so don't want to add one just for this -114 conn.addRequestProperty("Accept", "application/xml"); -115 conn.connect(); -116 -117 if (conn.getResponseCode() == 200) { -118 try { -119 final DocumentBuilder builder = DocumentBuilderFactory -120 .newInstance().newDocumentBuilder(); -121 final Document doc = builder.parse(conn.getInputStream()); -122 final XPath xpath = XPathFactory.newInstance().newXPath(); -123 final String groupId = xpath -124 .evaluate( -125 "/org.sonatype.nexus.rest.model.NexusArtifact/groupId", -126 doc); -127 final String artifactId = xpath.evaluate( -128 "/org.sonatype.nexus.rest.model.NexusArtifact/artifactId", -129 doc); -130 final String version = xpath +104 // JSON would be more elegant, but there's not currently a dependency +105 // on JSON, so don't want to add one just for this +106 conn.addRequestProperty("Accept", "application/xml"); +107 conn.connect(); +108 +109 if (conn.getResponseCode() == 200) { +110 try { +111 final DocumentBuilder builder = DocumentBuilderFactory +112 .newInstance().newDocumentBuilder(); +113 final Document doc = builder.parse(conn.getInputStream()); +114 final XPath xpath = XPathFactory.newInstance().newXPath(); +115 final String groupId = xpath +116 .evaluate( +117 "/org.sonatype.nexus.rest.model.NexusArtifact/groupId", +118 doc); +119 final String artifactId = xpath.evaluate( +120 "/org.sonatype.nexus.rest.model.NexusArtifact/artifactId", +121 doc); +122 final String version = xpath +123 .evaluate( +124 "/org.sonatype.nexus.rest.model.NexusArtifact/version", +125 doc); +126 final String link = xpath +127 .evaluate( +128 "/org.sonatype.nexus.rest.model.NexusArtifact/artifactLink", +129 doc); +130 final String pomLink = xpath 131 .evaluate( -132 "/org.sonatype.nexus.rest.model.NexusArtifact/version", +132 "/org.sonatype.nexus.rest.model.NexusArtifact/pomLink", 133 doc); -134 final String link = xpath -135 .evaluate( -136 "/org.sonatype.nexus.rest.model.NexusArtifact/artifactLink", -137 doc); -138 final String pomLink = xpath -139 .evaluate( -140 "/org.sonatype.nexus.rest.model.NexusArtifact/pomLink", -141 doc); -142 final MavenArtifact ma = new MavenArtifact(groupId, artifactId, version); -143 if (link != null && !"".equals(link)) { -144 ma.setArtifactUrl(link); -145 } -146 if (pomLink != null && !"".equals(pomLink)) { -147 ma.setPomUrl(pomLink); -148 } -149 return ma; -150 } catch (Throwable e) { -151 // Anything else is jacked-up XML stuff that we really can't recover -152 // from well -153 throw new IOException(e.getMessage(), e); -154 } -155 } else if (conn.getResponseCode() == 404) { -156 throw new FileNotFoundException("Artifact not found in Nexus"); -157 } else { -158 final String msg = String.format("Could not connect to Nexus received response code: %d %s", -159 conn.getResponseCode(), conn.getResponseMessage()); -160 LOGGER.fine(msg); -161 throw new IOException(msg); -162 } -163 } -164 -165 /** -166 * Do a preflight request to see if the repository is actually working. -167 * -168 * @return whether the repository is listening and returns the /status URL correctly -169 */ -170 public boolean preflightRequest() { -171 HttpURLConnection conn; -172 try { -173 final URL url = new URL(rootURL, "status"); -174 conn = URLConnectionFactory.createHttpURLConnection(url, useProxy); -175 conn.addRequestProperty("Accept", "application/xml"); -176 conn.connect(); -177 if (conn.getResponseCode() != 200) { -178 LOGGER.log(Level.WARNING, "Expected 200 result from Nexus, got {0}", conn.getResponseCode()); -179 return false; -180 } -181 final DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); -182 final Document doc = builder.parse(conn.getInputStream()); -183 if (!"status".equals(doc.getDocumentElement().getNodeName())) { -184 LOGGER.log(Level.WARNING, "Expected root node name of status, got {0}", doc.getDocumentElement().getNodeName()); -185 return false; -186 } -187 } catch (Throwable e) { -188 return false; -189 } -190 -191 return true; -192 } -193 } -194 -195 // vim: cc=120:sw=4:ts=4:sts=4 +134 final MavenArtifact ma = new MavenArtifact(groupId, artifactId, version); +135 if (link != null && !"".equals(link)) { +136 ma.setArtifactUrl(link); +137 } +138 if (pomLink != null && !"".equals(pomLink)) { +139 ma.setPomUrl(pomLink); +140 } +141 return ma; +142 } catch (Throwable e) { +143 // Anything else is jacked-up XML stuff that we really can't recover +144 // from well +145 throw new IOException(e.getMessage(), e); +146 } +147 } else if (conn.getResponseCode() == 404) { +148 throw new FileNotFoundException("Artifact not found in Nexus"); +149 } else { +150 LOGGER.debug("Could not connect to Nexus received response code: {} {}", +151 conn.getResponseCode(), conn.getResponseMessage()); +152 throw new IOException("Could not connect to Nexus"); +153 } +154 } +155 +156 /** +157 * Do a preflight request to see if the repository is actually working. +158 * +159 * @return whether the repository is listening and returns the /status URL correctly +160 */ +161 public boolean preflightRequest() { +162 HttpURLConnection conn; +163 try { +164 final URL url = new URL(rootURL, "status"); +165 conn = URLConnectionFactory.createHttpURLConnection(url, useProxy); +166 conn.addRequestProperty("Accept", "application/xml"); +167 conn.connect(); +168 if (conn.getResponseCode() != 200) { +169 LOGGER.warn("Expected 200 result from Nexus, got {}", conn.getResponseCode()); +170 return false; +171 } +172 final DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); +173 final Document doc = builder.parse(conn.getInputStream()); +174 if (!"status".equals(doc.getDocumentElement().getNodeName())) { +175 LOGGER.warn("Expected root node name of status, got {}", doc.getDocumentElement().getNodeName()); +176 return false; +177 } +178 } catch (Throwable e) { +179 return false; +180 } +181 +182 return true; +183 } +184 } +185 +186 // vim: cc=120:sw=4:ts=4:sts=4
    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 bbf385408..b2d257321 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.2.11 Reference Package org.owasp.dependencycheck.data.nexus + Dependency-Check Core 1.3.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 57c9e2d3c..7cbf88bdf 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.2.11 Reference Package org.owasp.dependencycheck.data.nexus + Dependency-Check Core 1.3.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 063844b15..9350bef04 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.2.11 Reference Package org.owasp.dependencycheck.data.nuget + Dependency-Check Core 1.3.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 cfd452ffe..43e4b8c7a 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.2.11 Reference Package org.owasp.dependencycheck.data.nuget + Dependency-Check Core 1.3.0 Reference Package org.owasp.dependencycheck.data.nuget diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/ConnectionFactory.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/ConnectionFactory.html index 28798ebe1..d61c01ae9 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/ConnectionFactory.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/ConnectionFactory.html @@ -37,208 +37,208 @@ 29 import java.sql.ResultSet; 30 import java.sql.SQLException; 31 import java.sql.Statement; -32 import java.util.logging.Level; -33 import java.util.logging.Logger; -34 import org.owasp.dependencycheck.utils.DBUtils; -35 import org.owasp.dependencycheck.utils.Settings; +32 import org.owasp.dependencycheck.utils.DBUtils; +33 import org.owasp.dependencycheck.utils.Settings; +34 import org.slf4j.Logger; +35 import org.slf4j.LoggerFactory; 36 37 /** -38 * Loads the configured database driver and returns the database connection. If the embedded H2 database is used -39 * obtaining a connection will ensure the database file exists and that the appropriate table structure has been -40 * created. -41 * -42 * @author Jeremy Long -43 */ -44 public final class ConnectionFactory { -45 -46 /** -47 * The Logger. -48 */ -49 private static final Logger LOGGER = Logger.getLogger(ConnectionFactory.class.getName()); -50 /** -51 * The version of the current DB Schema. -52 */ -53 public static final String DB_SCHEMA_VERSION = Settings.getString(Settings.KEYS.DB_VERSION); -54 /** -55 * Resource location for SQL file used to create the database schema. -56 */ -57 public static final String DB_STRUCTURE_RESOURCE = "data/initialize.sql"; -58 /** -59 * The database driver used to connect to the database. -60 */ -61 private static Driver driver = null; -62 /** -63 * The database connection string. -64 */ -65 private static String connectionString = null; -66 /** -67 * The username to connect to the database. -68 */ -69 private static String userName = null; -70 /** -71 * The password for the database. -72 */ -73 private static String password = null; -74 -75 /** -76 * Private constructor for this factory class; no instance is ever needed. -77 */ -78 private ConnectionFactory() { -79 } -80 -81 /** -82 * Initializes the connection factory. Ensuring that the appropriate drivers are loaded and that a connection can be -83 * made successfully. -84 * -85 * @throws DatabaseException thrown if we are unable to connect to the database -86 */ -87 public static synchronized void initialize() throws DatabaseException { -88 //this only needs to be called once. -89 if (connectionString != null) { -90 return; -91 } -92 Connection conn = null; -93 try { -94 //load the driver if necessary -95 final String driverName = Settings.getString(Settings.KEYS.DB_DRIVER_NAME, ""); -96 if (!driverName.isEmpty()) { //likely need to load the correct driver -97 LOGGER.log(Level.FINE, "Loading driver: {0}", driverName); -98 final String driverPath = Settings.getString(Settings.KEYS.DB_DRIVER_PATH, ""); -99 try { -100 if (!driverPath.isEmpty()) { -101 LOGGER.log(Level.FINE, "Loading driver from: {0}", driverPath); -102 driver = DriverLoader.load(driverName, driverPath); -103 } else { -104 driver = DriverLoader.load(driverName); -105 } -106 } catch (DriverLoadException ex) { -107 LOGGER.log(Level.FINE, "Unable to load database driver", ex); -108 throw new DatabaseException("Unable to load database driver"); -109 } -110 } -111 userName = Settings.getString(Settings.KEYS.DB_USER, "dcuser"); -112 //yes, yes - hard-coded password - only if there isn't one in the properties file. -113 password = Settings.getString(Settings.KEYS.DB_PASSWORD, "DC-Pass1337!"); -114 try { -115 connectionString = Settings.getConnectionString( -116 Settings.KEYS.DB_CONNECTION_STRING, -117 Settings.KEYS.DB_FILE_NAME, -118 Settings.KEYS.DB_VERSION); -119 } catch (IOException ex) { -120 LOGGER.log(Level.FINE, -121 "Unable to retrieve the database connection string", ex); -122 throw new DatabaseException("Unable to retrieve the database connection string"); -123 } -124 boolean shouldCreateSchema = false; -125 try { -126 if (connectionString.startsWith("jdbc:h2:file:")) { //H2 -127 shouldCreateSchema = !h2DataFileExists(); -128 LOGGER.log(Level.FINE, "Need to create DB Structure: {0}", shouldCreateSchema); -129 } -130 } catch (IOException ioex) { -131 LOGGER.log(Level.FINE, "Unable to verify database exists", ioex); -132 throw new DatabaseException("Unable to verify database exists"); -133 } -134 LOGGER.log(Level.FINE, "Loading database connection"); -135 LOGGER.log(Level.FINE, "Connection String: {0}", connectionString); -136 LOGGER.log(Level.FINE, "Database User: {0}", userName); -137 -138 try { -139 conn = DriverManager.getConnection(connectionString, userName, password); -140 } catch (SQLException ex) { -141 if (ex.getMessage().contains("java.net.UnknownHostException") && connectionString.contains("AUTO_SERVER=TRUE;")) { -142 connectionString = connectionString.replace("AUTO_SERVER=TRUE;", ""); -143 try { -144 conn = DriverManager.getConnection(connectionString, userName, password); -145 Settings.setString(Settings.KEYS.DB_CONNECTION_STRING, connectionString); -146 LOGGER.log(Level.FINE, -147 "Unable to start the database in server mode; reverting to single user mode"); -148 } catch (SQLException sqlex) { -149 LOGGER.log(Level.FINE, "Unable to connect to the database", ex); -150 throw new DatabaseException("Unable to connect to the database"); -151 } -152 } else { -153 LOGGER.log(Level.FINE, "Unable to connect to the database", ex); -154 throw new DatabaseException("Unable to connect to the database"); -155 } -156 } -157 -158 if (shouldCreateSchema) { -159 try { -160 createTables(conn); -161 } catch (DatabaseException dex) { -162 LOGGER.log(Level.FINE, null, dex); -163 throw new DatabaseException("Unable to create the database structure"); -164 } -165 } else { -166 try { -167 ensureSchemaVersion(conn); -168 } catch (DatabaseException dex) { -169 LOGGER.log(Level.FINE, null, dex); -170 throw new DatabaseException("Database schema does not match this version of dependency-check"); -171 } -172 } -173 } finally { -174 if (conn != null) { -175 try { -176 conn.close(); -177 } catch (SQLException ex) { -178 LOGGER.log(Level.FINE, "An error occurred closing the connection", ex); -179 } -180 } -181 } -182 } -183 -184 /** -185 * Cleans up resources and unloads any registered database drivers. This needs to be called to ensure the driver is -186 * unregistered prior to the finalize method being called as during shutdown the class loader used to load the -187 * driver may be unloaded prior to the driver being de-registered. -188 */ -189 public static synchronized void cleanup() { -190 if (driver != null) { -191 try { -192 DriverManager.deregisterDriver(driver); -193 } catch (SQLException ex) { -194 LOGGER.log(Level.FINE, "An error occurred unloading the database driver", ex); -195 } catch (Throwable unexpected) { -196 LOGGER.log(Level.FINE, -197 "An unexpected throwable occurred unloading the database driver", unexpected); -198 } -199 driver = null; -200 } -201 connectionString = null; -202 userName = null; -203 password = null; -204 } -205 -206 /** -207 * Constructs a new database connection object per the database configuration. -208 * -209 * @return a database connection object -210 * @throws DatabaseException thrown if there is an exception loading the database connection -211 */ -212 public static Connection getConnection() throws DatabaseException { -213 initialize(); -214 Connection conn = null; -215 try { -216 conn = DriverManager.getConnection(connectionString, userName, password); -217 } catch (SQLException ex) { -218 LOGGER.log(Level.FINE, null, ex); -219 throw new DatabaseException("Unable to connect to the database"); -220 } -221 return conn; -222 } -223 -224 /** -225 * Determines if the H2 database file exists. If it does not exist then the data structure will need to be created. -226 * -227 * @return true if the H2 database file does not exist; otherwise false -228 * @throws IOException thrown if the data directory does not exist and cannot be created -229 */ -230 private static boolean h2DataFileExists() throws IOException { -231 final File dir = Settings.getDataDirectory(); -232 final String name = Settings.getString(Settings.KEYS.DB_FILE_NAME); -233 final String fileName = String.format(name, DB_SCHEMA_VERSION); +38 * Loads the configured database driver and returns the database connection. If the embedded H2 database is used obtaining a +39 * connection will ensure the database file exists and that the appropriate table structure has been created. +40 * +41 * @author Jeremy Long +42 */ +43 public final class ConnectionFactory { +44 +45 /** +46 * The Logger. +47 */ +48 private static final Logger LOGGER = LoggerFactory.getLogger(ConnectionFactory.class); +49 /** +50 * The version of the current DB Schema. +51 */ +52 public static final String DB_SCHEMA_VERSION = Settings.getString(Settings.KEYS.DB_VERSION); +53 /** +54 * Resource location for SQL file used to create the database schema. +55 */ +56 public static final String DB_STRUCTURE_RESOURCE = "data/initialize.sql"; +57 /** +58 * Resource location for SQL file used to create the database schema. +59 */ +60 public static final String DB_STRUCTURE_UPDATE_RESOURCE = "data/upgrade_%s.sql"; +61 /** +62 * The database driver used to connect to the database. +63 */ +64 private static Driver driver = null; +65 /** +66 * The database connection string. +67 */ +68 private static String connectionString = null; +69 /** +70 * The username to connect to the database. +71 */ +72 private static String userName = null; +73 /** +74 * The password for the database. +75 */ +76 private static String password = null; +77 +78 /** +79 * Private constructor for this factory class; no instance is ever needed. +80 */ +81 private ConnectionFactory() { +82 } +83 +84 /** +85 * Initializes the connection factory. Ensuring that the appropriate drivers are loaded and that a connection can be made +86 * successfully. +87 * +88 * @throws DatabaseException thrown if we are unable to connect to the database +89 */ +90 public static synchronized void initialize() throws DatabaseException { +91 //this only needs to be called once. +92 if (connectionString != null) { +93 return; +94 } +95 Connection conn = null; +96 try { +97 //load the driver if necessary +98 final String driverName = Settings.getString(Settings.KEYS.DB_DRIVER_NAME, ""); +99 if (!driverName.isEmpty()) { //likely need to load the correct driver +100 LOGGER.debug("Loading driver: {}", driverName); +101 final String driverPath = Settings.getString(Settings.KEYS.DB_DRIVER_PATH, ""); +102 try { +103 if (!driverPath.isEmpty()) { +104 LOGGER.debug("Loading driver from: {}", driverPath); +105 driver = DriverLoader.load(driverName, driverPath); +106 } else { +107 driver = DriverLoader.load(driverName); +108 } +109 } catch (DriverLoadException ex) { +110 LOGGER.debug("Unable to load database driver", ex); +111 throw new DatabaseException("Unable to load database driver"); +112 } +113 } +114 userName = Settings.getString(Settings.KEYS.DB_USER, "dcuser"); +115 //yes, yes - hard-coded password - only if there isn't one in the properties file. +116 password = Settings.getString(Settings.KEYS.DB_PASSWORD, "DC-Pass1337!"); +117 try { +118 connectionString = Settings.getConnectionString( +119 Settings.KEYS.DB_CONNECTION_STRING, +120 Settings.KEYS.DB_FILE_NAME); +121 } catch (IOException ex) { +122 LOGGER.debug( +123 "Unable to retrieve the database connection string", ex); +124 throw new DatabaseException("Unable to retrieve the database connection string"); +125 } +126 boolean shouldCreateSchema = false; +127 try { +128 if (connectionString.startsWith("jdbc:h2:file:")) { //H2 +129 shouldCreateSchema = !h2DataFileExists(); +130 LOGGER.debug("Need to create DB Structure: {}", shouldCreateSchema); +131 } +132 } catch (IOException ioex) { +133 LOGGER.debug("Unable to verify database exists", ioex); +134 throw new DatabaseException("Unable to verify database exists"); +135 } +136 LOGGER.debug("Loading database connection"); +137 LOGGER.debug("Connection String: {}", connectionString); +138 LOGGER.debug("Database User: {}", userName); +139 +140 try { +141 conn = DriverManager.getConnection(connectionString, userName, password); +142 } catch (SQLException ex) { +143 if (ex.getMessage().contains("java.net.UnknownHostException") && connectionString.contains("AUTO_SERVER=TRUE;")) { +144 connectionString = connectionString.replace("AUTO_SERVER=TRUE;", ""); +145 try { +146 conn = DriverManager.getConnection(connectionString, userName, password); +147 Settings.setString(Settings.KEYS.DB_CONNECTION_STRING, connectionString); +148 LOGGER.debug( +149 "Unable to start the database in server mode; reverting to single user mode"); +150 } catch (SQLException sqlex) { +151 LOGGER.debug("Unable to connect to the database", ex); +152 throw new DatabaseException("Unable to connect to the database"); +153 } +154 } else { +155 LOGGER.debug("Unable to connect to the database", ex); +156 throw new DatabaseException("Unable to connect to the database"); +157 } +158 } +159 +160 if (shouldCreateSchema) { +161 try { +162 createTables(conn); +163 } catch (DatabaseException dex) { +164 LOGGER.debug("", dex); +165 throw new DatabaseException("Unable to create the database structure"); +166 } +167 } +168 try { +169 ensureSchemaVersion(conn); +170 } catch (DatabaseException dex) { +171 LOGGER.debug("", dex); +172 throw new DatabaseException("Database schema does not match this version of dependency-check", dex); +173 } +174 } finally { +175 if (conn != null) { +176 try { +177 conn.close(); +178 } catch (SQLException ex) { +179 LOGGER.debug("An error occurred closing the connection", ex); +180 } +181 } +182 } +183 } +184 +185 /** +186 * Cleans up resources and unloads any registered database drivers. This needs to be called to ensure the driver is +187 * unregistered prior to the finalize method being called as during shutdown the class loader used to load the driver may be +188 * unloaded prior to the driver being de-registered. +189 */ +190 public static synchronized void cleanup() { +191 if (driver != null) { +192 try { +193 DriverManager.deregisterDriver(driver); +194 } catch (SQLException ex) { +195 LOGGER.debug("An error occurred unloading the database driver", ex); +196 } catch (Throwable unexpected) { +197 LOGGER.debug( +198 "An unexpected throwable occurred unloading the database driver", unexpected); +199 } +200 driver = null; +201 } +202 connectionString = null; +203 userName = null; +204 password = null; +205 } +206 +207 /** +208 * Constructs a new database connection object per the database configuration. +209 * +210 * @return a database connection object +211 * @throws DatabaseException thrown if there is an exception loading the database connection +212 */ +213 public static Connection getConnection() throws DatabaseException { +214 initialize(); +215 Connection conn = null; +216 try { +217 conn = DriverManager.getConnection(connectionString, userName, password); +218 } catch (SQLException ex) { +219 LOGGER.debug("", ex); +220 throw new DatabaseException("Unable to connect to the database"); +221 } +222 return conn; +223 } +224 +225 /** +226 * Determines if the H2 database file exists. If it does not exist then the data structure will need to be created. +227 * +228 * @return true if the H2 database file does not exist; otherwise false +229 * @throws IOException thrown if the data directory does not exist and cannot be created +230 */ +231 private static boolean h2DataFileExists() throws IOException { +232 final File dir = Settings.getDataDirectory(); +233 final String fileName = Settings.getString(Settings.KEYS.DB_FILE_NAME); 234 final File file = new File(dir, fileName); 235 return file.exists(); 236 } @@ -250,7 +250,7 @@ 242 * @throws DatabaseException thrown if there is a Database Exception 243 */ 244 private static void createTables(Connection conn) throws DatabaseException { -245 LOGGER.log(Level.FINE, "Creating database structure"); +245 LOGGER.debug("Creating database structure"); 246 InputStream is; 247 InputStreamReader reader; 248 BufferedReader in = null; @@ -268,7 +268,7 @@ 260 statement = conn.createStatement(); 261 statement.execute(sb.toString()); 262 } catch (SQLException ex) { -263 LOGGER.log(Level.FINE, null, ex); +263 LOGGER.debug("", ex); 264 throw new DatabaseException("Unable to create database statement", ex); 265 } finally { 266 DBUtils.closeStatement(statement); @@ -280,41 +280,95 @@ 272 try { 273 in.close(); 274 } catch (IOException ex) { -275 LOGGER.log(Level.FINEST, null, ex); +275 LOGGER.trace("", ex); 276 } 277 } 278 } 279 } 280 281 /** -282 * Uses the provided connection to check the specified schema version within the database. -283 * -284 * @param conn the database connection object -285 * @throws DatabaseException thrown if the schema version is not compatible with this version of dependency-check -286 */ -287 private static void ensureSchemaVersion(Connection conn) throws DatabaseException { -288 ResultSet rs = null; -289 CallableStatement cs = null; -290 try { -291 cs = conn.prepareCall("SELECT value FROM properties WHERE id = 'version'"); -292 rs = cs.executeQuery(); -293 if (rs.next()) { -294 final boolean isWrongSchema = !DB_SCHEMA_VERSION.equals(rs.getString(1)); -295 if (isWrongSchema) { -296 throw new DatabaseException("Incorrect database schema; unable to continue"); -297 } -298 } else { -299 throw new DatabaseException("Database schema is missing"); -300 } -301 } catch (SQLException ex) { -302 LOGGER.log(Level.FINE, null, ex); -303 throw new DatabaseException("Unable to check the database schema version"); -304 } finally { -305 DBUtils.closeResultSet(rs); -306 DBUtils.closeStatement(cs); -307 } -308 } -309 } +282 * Updates the database schema by loading the upgrade script for the version specified. The intended use is that if the +283 * current schema version is 2.9 then we would call updateSchema(conn, "2.9"). This would load the upgrade_2.9.sql file and +284 * execute it against the database. The upgrade script must update the 'version' in the properties table. +285 * +286 * @param conn the database connection object +287 * @param schema the current schema version that is being upgraded +288 * @throws DatabaseException thrown if there is an exception upgrading the database schema +289 */ +290 private static void updateSchema(Connection conn, String schema) throws DatabaseException { +291 LOGGER.debug("Updating database structure"); +292 InputStream is; +293 InputStreamReader reader; +294 BufferedReader in = null; +295 String updateFile = null; +296 try { +297 updateFile = String.format(DB_STRUCTURE_UPDATE_RESOURCE, schema); +298 is = ConnectionFactory.class.getClassLoader().getResourceAsStream(updateFile); +299 if (is == null) { +300 throw new DatabaseException(String.format("Unable to load update file '%s'", updateFile)); +301 } +302 reader = new InputStreamReader(is, "UTF-8"); +303 in = new BufferedReader(reader); +304 final StringBuilder sb = new StringBuilder(2110); +305 String tmp; +306 while ((tmp = in.readLine()) != null) { +307 sb.append(tmp); +308 } +309 Statement statement = null; +310 try { +311 statement = conn.createStatement(); +312 statement.execute(sb.toString()); +313 } catch (SQLException ex) { +314 LOGGER.debug("", ex); +315 throw new DatabaseException("Unable to update database schema", ex); +316 } finally { +317 DBUtils.closeStatement(statement); +318 } +319 } catch (IOException ex) { +320 final String msg = String.format("Upgrade SQL file does not exist: %s", updateFile); +321 throw new DatabaseException(msg, ex); +322 } finally { +323 if (in != null) { +324 try { +325 in.close(); +326 } catch (IOException ex) { +327 LOGGER.trace("", ex); +328 } +329 } +330 } +331 } +332 +333 /** +334 * Uses the provided connection to check the specified schema version within the database. +335 * +336 * @param conn the database connection object +337 * @throws DatabaseException thrown if the schema version is not compatible with this version of dependency-check +338 */ +339 private static void ensureSchemaVersion(Connection conn) throws DatabaseException { +340 ResultSet rs = null; +341 CallableStatement cs = null; +342 try { +343 //TODO convert this to use DatabaseProperties +344 cs = conn.prepareCall("SELECT value FROM properties WHERE id = 'version'"); +345 rs = cs.executeQuery(); +346 if (rs.next()) { +347 if (!DB_SCHEMA_VERSION.equals(rs.getString(1))) { +348 LOGGER.debug("Current Schema: " + DB_SCHEMA_VERSION); +349 LOGGER.debug("DB Schema: " + rs.getString(1)); +350 updateSchema(conn, rs.getString(1)); +351 } +352 } else { +353 throw new DatabaseException("Database schema is missing"); +354 } +355 } catch (SQLException ex) { +356 LOGGER.debug("", ex); +357 throw new DatabaseException("Unable to check the database schema version"); +358 } finally { +359 DBUtils.closeResultSet(rs); +360 DBUtils.closeStatement(cs); +361 } +362 } +363 }
    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 18609535d..c8ee9c76f 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 @@ -27,773 +27,806 @@ 19 20 import java.io.IOException; 21 import java.io.UnsupportedEncodingException; -22 import java.sql.Connection; -23 import java.sql.PreparedStatement; -24 import java.sql.ResultSet; -25 import java.sql.SQLException; -26 import java.sql.Statement; -27 import java.util.ArrayList; -28 import java.util.HashMap; -29 import java.util.HashSet; -30 import java.util.List; -31 import java.util.Map; -32 import java.util.Map.Entry; -33 import java.util.Properties; -34 import java.util.ResourceBundle; -35 import java.util.Set; -36 import java.util.logging.Level; -37 import java.util.logging.Logger; -38 import org.owasp.dependencycheck.data.cwe.CweDB; -39 import org.owasp.dependencycheck.dependency.Reference; -40 import org.owasp.dependencycheck.dependency.Vulnerability; -41 import org.owasp.dependencycheck.dependency.VulnerableSoftware; -42 import org.owasp.dependencycheck.utils.DBUtils; -43 import org.owasp.dependencycheck.utils.DependencyVersion; -44 import org.owasp.dependencycheck.utils.DependencyVersionUtil; -45 import org.owasp.dependencycheck.utils.Pair; -46 import org.owasp.dependencycheck.utils.Settings; -47 -48 /** -49 * The database holding information about the NVD CVE data. -50 * -51 * @author Jeremy Long -52 */ -53 public class CveDB { -54 -55 /** -56 * The logger. -57 */ -58 private static final Logger LOGGER = Logger.getLogger(CveDB.class.getName()); -59 /** -60 * Database connection -61 */ -62 private Connection conn; -63 /** -64 * The bundle of statements used when accessing the database. -65 */ -66 private ResourceBundle statementBundle = null; -67 -68 /** -69 * Creates a new CveDB object and opens the database connection. Note, the connection must be closed by the caller by calling -70 * the close method. -71 * -72 * @throws DatabaseException thrown if there is an exception opening the database. -73 */ -74 public CveDB() throws DatabaseException { -75 super(); -76 statementBundle = java.util.ResourceBundle.getBundle("data/dbStatements"); -77 try { -78 open(); -79 databaseProperties = new DatabaseProperties(this); -80 } catch (DatabaseException ex) { -81 throw ex; -82 } -83 } -84 -85 /** -86 * Returns the database connection. -87 * -88 * @return the database connection -89 */ -90 protected Connection getConnection() { -91 return conn; -92 } -93 -94 /** -95 * Opens the database connection. If the database does not exist, it will create a new one. -96 * -97 * @throws DatabaseException thrown if there is an error opening the database connection -98 */ -99 public final void open() throws DatabaseException { -100 if (!isOpen()) { -101 conn = ConnectionFactory.getConnection(); -102 } -103 } -104 -105 /** -106 * Closes the DB4O database. Close should be called on this object when it is done being used. -107 */ -108 public void close() { -109 if (conn != null) { -110 try { -111 conn.close(); -112 } catch (SQLException ex) { -113 final String msg = "There was an error attempting to close the CveDB, see the log for more details."; -114 LOGGER.log(Level.SEVERE, msg); -115 LOGGER.log(Level.FINE, null, ex); +22 import java.sql.CallableStatement; +23 import java.sql.Connection; +24 import java.sql.PreparedStatement; +25 import java.sql.ResultSet; +26 import java.sql.SQLException; +27 import java.sql.Statement; +28 import java.util.ArrayList; +29 import java.util.HashMap; +30 import java.util.HashSet; +31 import java.util.List; +32 import java.util.Map; +33 import java.util.Map.Entry; +34 import java.util.Properties; +35 import java.util.ResourceBundle; +36 import java.util.Set; +37 import org.owasp.dependencycheck.data.cwe.CweDB; +38 import org.owasp.dependencycheck.dependency.Reference; +39 import org.owasp.dependencycheck.dependency.Vulnerability; +40 import org.owasp.dependencycheck.dependency.VulnerableSoftware; +41 import org.owasp.dependencycheck.utils.DBUtils; +42 import org.owasp.dependencycheck.utils.DependencyVersion; +43 import org.owasp.dependencycheck.utils.DependencyVersionUtil; +44 import org.owasp.dependencycheck.utils.Pair; +45 import org.owasp.dependencycheck.utils.Settings; +46 import org.slf4j.Logger; +47 import org.slf4j.LoggerFactory; +48 +49 /** +50 * The database holding information about the NVD CVE data. +51 * +52 * @author Jeremy Long +53 */ +54 public class CveDB { +55 +56 /** +57 * The logger. +58 */ +59 private static final Logger LOGGER = LoggerFactory.getLogger(CveDB.class); +60 /** +61 * Database connection +62 */ +63 private Connection conn; +64 /** +65 * The bundle of statements used when accessing the database. +66 */ +67 private ResourceBundle statementBundle = null; +68 +69 /** +70 * Creates a new CveDB object and opens the database connection. Note, the connection must be closed by the caller by calling +71 * the close method. +72 * +73 * @throws DatabaseException thrown if there is an exception opening the database. +74 */ +75 public CveDB() throws DatabaseException { +76 super(); +77 statementBundle = ResourceBundle.getBundle("data/dbStatements"); +78 try { +79 open(); +80 databaseProperties = new DatabaseProperties(this); +81 } catch (DatabaseException ex) { +82 throw ex; +83 } +84 } +85 +86 /** +87 * Returns the database connection. +88 * +89 * @return the database connection +90 */ +91 protected Connection getConnection() { +92 return conn; +93 } +94 +95 /** +96 * Opens the database connection. If the database does not exist, it will create a new one. +97 * +98 * @throws DatabaseException thrown if there is an error opening the database connection +99 */ +100 public final void open() throws DatabaseException { +101 if (!isOpen()) { +102 conn = ConnectionFactory.getConnection(); +103 } +104 } +105 +106 /** +107 * Closes the DB4O database. Close should be called on this object when it is done being used. +108 */ +109 public void close() { +110 if (conn != null) { +111 try { +112 conn.close(); +113 } catch (SQLException ex) { +114 LOGGER.error("There was an error attempting to close the CveDB, see the log for more details."); +115 LOGGER.debug("", ex); 116 } catch (Throwable ex) { -117 final String msg = "There was an exception attempting to close the CveDB, see the log for more details."; -118 LOGGER.log(Level.SEVERE, msg); -119 LOGGER.log(Level.FINE, null, ex); -120 } -121 conn = null; -122 } -123 } -124 -125 /** -126 * Returns whether the database connection is open or closed. -127 * -128 * @return whether the database connection is open or closed -129 */ -130 public boolean isOpen() { -131 return conn != null; -132 } -133 -134 /** -135 * Commits all completed transactions. -136 * -137 * @throws SQLException thrown if a SQL Exception occurs -138 */ -139 public void commit() throws SQLException { -140 //temporary remove this as autocommit is on. -141 //if (conn != null) { -142 // conn.commit(); -143 //} -144 } -145 -146 /** -147 * Cleans up the object and ensures that "close" has been called. -148 * -149 * @throws Throwable thrown if there is a problem -150 */ -151 @Override -152 @SuppressWarnings("FinalizeDeclaration") -153 protected void finalize() throws Throwable { -154 LOGGER.log(Level.FINE, "Entering finalize"); -155 close(); -156 super.finalize(); -157 } -158 /** -159 * Database properties object containing the 'properties' from the database table. -160 */ -161 private DatabaseProperties databaseProperties; -162 -163 /** -164 * Get the value of databaseProperties. -165 * -166 * @return the value of databaseProperties -167 */ -168 public DatabaseProperties getDatabaseProperties() { -169 return databaseProperties; -170 } -171 -172 /** -173 * Searches the CPE entries in the database and retrieves all entries for a given vendor and product combination. The returned -174 * list will include all versions of the product that are registered in the NVD CVE data. -175 * -176 * @param vendor the identified vendor name of the dependency being analyzed -177 * @param product the identified name of the product of the dependency being analyzed -178 * @return a set of vulnerable software -179 */ -180 public Set<VulnerableSoftware> getCPEs(String vendor, String product) { -181 final Set<VulnerableSoftware> cpe = new HashSet<VulnerableSoftware>(); -182 ResultSet rs = null; -183 PreparedStatement ps = null; -184 try { -185 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_CPE_ENTRIES")); -186 ps.setString(1, vendor); -187 ps.setString(2, product); -188 rs = ps.executeQuery(); -189 -190 while (rs.next()) { -191 final VulnerableSoftware vs = new VulnerableSoftware(); -192 vs.setCpe(rs.getString(1)); -193 cpe.add(vs); -194 } -195 } catch (SQLException ex) { -196 final String msg = "An unexpected SQL Exception occurred; please see the verbose log for more details."; -197 LOGGER.log(Level.SEVERE, msg); -198 LOGGER.log(Level.FINE, null, ex); -199 } finally { -200 DBUtils.closeResultSet(rs); -201 DBUtils.closeStatement(ps); -202 } -203 return cpe; -204 } -205 -206 /** -207 * Returns the entire list of vendor/product combinations. -208 * -209 * @return the entire list of vendor/product combinations -210 * @throws DatabaseException thrown when there is an error retrieving the data from the DB -211 */ -212 public Set<Pair<String, String>> getVendorProductList() throws DatabaseException { -213 final Set<Pair<String, String>> data = new HashSet<Pair<String, String>>(); -214 ResultSet rs = null; -215 PreparedStatement ps = null; -216 try { -217 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_VENDOR_PRODUCT_LIST")); -218 rs = ps.executeQuery(); -219 while (rs.next()) { -220 data.add(new Pair<String, String>(rs.getString(1), rs.getString(2))); -221 } -222 } catch (SQLException ex) { -223 final String msg = "An unexpected SQL Exception occurred; please see the verbose log for more details."; -224 throw new DatabaseException(msg, ex); -225 } finally { -226 DBUtils.closeResultSet(rs); -227 DBUtils.closeStatement(ps); -228 } -229 return data; -230 } -231 -232 /** -233 * Returns a set of properties. -234 * -235 * @return the properties from the database -236 */ -237 Properties getProperties() { -238 final Properties prop = new Properties(); -239 PreparedStatement ps = null; -240 ResultSet rs = null; -241 try { -242 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_PROPERTIES")); -243 rs = ps.executeQuery(); -244 while (rs.next()) { -245 prop.setProperty(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 LOGGER.log(Level.SEVERE, msg); -250 LOGGER.log(Level.FINE, null, ex); -251 } finally { -252 DBUtils.closeStatement(ps); -253 DBUtils.closeResultSet(rs); -254 } -255 return prop; -256 } -257 -258 /** -259 * Saves a set of properties to the database. -260 * -261 * @param props a collection of properties -262 */ -263 void saveProperties(Properties props) { -264 PreparedStatement updateProperty = null; -265 PreparedStatement insertProperty = null; -266 try { -267 try { -268 updateProperty = getConnection().prepareStatement(statementBundle.getString("UPDATE_PROPERTY")); -269 insertProperty = getConnection().prepareStatement(statementBundle.getString("INSERT_PROPERTY")); -270 } catch (SQLException ex) { -271 LOGGER.log(Level.WARNING, "Unable to save properties to the database"); -272 LOGGER.log(Level.FINE, "Unable to save properties to the database", ex); -273 return; -274 } -275 for (Entry<Object, Object> entry : props.entrySet()) { -276 final String key = entry.getKey().toString(); -277 final String value = entry.getValue().toString(); -278 try { -279 updateProperty.setString(1, value); -280 updateProperty.setString(2, key); -281 if (updateProperty.executeUpdate() == 0) { -282 insertProperty.setString(1, key); -283 insertProperty.setString(2, value); -284 } -285 } catch (SQLException ex) { -286 final String msg = String.format("Unable to save property '%s' with a value of '%s' to the database", key, value); -287 LOGGER.log(Level.WARNING, msg); -288 LOGGER.log(Level.FINE, null, ex); -289 } -290 } -291 } finally { -292 DBUtils.closeStatement(updateProperty); -293 DBUtils.closeStatement(insertProperty); -294 } -295 } -296 -297 /** -298 * Saves a property to the database. -299 * -300 * @param key the property key -301 * @param value the property value -302 */ -303 void saveProperty(String key, String value) { -304 PreparedStatement updateProperty = null; -305 PreparedStatement insertProperty = null; -306 try { -307 try { -308 updateProperty = getConnection().prepareStatement(statementBundle.getString("UPDATE_PROPERTY")); -309 } catch (SQLException ex) { -310 LOGGER.log(Level.WARNING, "Unable to save properties to the database"); -311 LOGGER.log(Level.FINE, "Unable to save properties to the database", ex); -312 return; -313 } -314 try { -315 updateProperty.setString(1, value); -316 updateProperty.setString(2, key); -317 if (updateProperty.executeUpdate() == 0) { -318 try { -319 insertProperty = getConnection().prepareStatement(statementBundle.getString("INSERT_PROPERTY")); -320 } catch (SQLException ex) { -321 LOGGER.log(Level.WARNING, "Unable to save properties to the database"); -322 LOGGER.log(Level.FINE, "Unable to save properties to the database", ex); -323 return; -324 } -325 insertProperty.setString(1, key); -326 insertProperty.setString(2, value); -327 insertProperty.execute(); -328 } -329 } catch (SQLException ex) { -330 final String msg = String.format("Unable to save property '%s' with a value of '%s' to the database", key, value); -331 LOGGER.log(Level.WARNING, msg); -332 LOGGER.log(Level.FINE, null, ex); -333 } -334 } finally { -335 DBUtils.closeStatement(updateProperty); -336 DBUtils.closeStatement(insertProperty); -337 } -338 } -339 -340 /** -341 * Retrieves the vulnerabilities associated with the specified CPE. -342 * -343 * @param cpeStr the CPE name -344 * @return a list of Vulnerabilities -345 * @throws DatabaseException thrown if there is an exception retrieving data -346 */ -347 public List<Vulnerability> getVulnerabilities(String cpeStr) throws DatabaseException { -348 ResultSet rs = null; -349 final VulnerableSoftware cpe = new VulnerableSoftware(); -350 try { -351 cpe.parseName(cpeStr); -352 } catch (UnsupportedEncodingException ex) { -353 LOGGER.log(Level.FINEST, null, ex); -354 } -355 final DependencyVersion detectedVersion = parseDependencyVersion(cpe); -356 final List<Vulnerability> vulnerabilities = new ArrayList<Vulnerability>(); -357 -358 PreparedStatement ps; -359 try { -360 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_CVE_FROM_SOFTWARE")); -361 ps.setString(1, cpe.getVendor()); -362 ps.setString(2, cpe.getProduct()); -363 rs = ps.executeQuery(); -364 String currentCVE = ""; -365 -366 final Map<String, Boolean> vulnSoftware = new HashMap<String, Boolean>(); -367 while (rs.next()) { -368 final String cveId = rs.getString(1); -369 if (!currentCVE.equals(cveId)) { //check for match and add -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 vulnSoftware.clear(); -377 currentCVE = cveId; -378 } -379 -380 final String cpeId = rs.getString(2); -381 final String previous = rs.getString(3); -382 final Boolean p = previous != null && !previous.isEmpty(); -383 vulnSoftware.put(cpeId, p); -384 } -385 //remember to process the last set of CVE/CPE entries -386 final Entry<String, Boolean> matchedCPE = getMatchingSoftware(vulnSoftware, cpe.getVendor(), cpe.getProduct(), detectedVersion); -387 if (matchedCPE != null) { -388 final Vulnerability v = getVulnerability(currentCVE); -389 v.setMatchedCPE(matchedCPE.getKey(), matchedCPE.getValue() ? "Y" : null); -390 vulnerabilities.add(v); -391 } +117 LOGGER.error("There was an exception attempting to close the CveDB, see the log for more details."); +118 LOGGER.debug("", ex); +119 } +120 conn = null; +121 } +122 } +123 +124 /** +125 * Returns whether the database connection is open or closed. +126 * +127 * @return whether the database connection is open or closed +128 */ +129 public boolean isOpen() { +130 return conn != null; +131 } +132 +133 /** +134 * Commits all completed transactions. +135 * +136 * @throws SQLException thrown if a SQL Exception occurs +137 */ +138 public void commit() throws SQLException { +139 //temporary remove this as autocommit is on. +140 //if (conn != null) { +141 // conn.commit(); +142 //} +143 } +144 +145 /** +146 * Cleans up the object and ensures that "close" has been called. +147 * +148 * @throws Throwable thrown if there is a problem +149 */ +150 @Override +151 @SuppressWarnings("FinalizeDeclaration") +152 protected void finalize() throws Throwable { +153 LOGGER.debug("Entering finalize"); +154 close(); +155 super.finalize(); +156 } +157 /** +158 * Database properties object containing the 'properties' from the database table. +159 */ +160 private DatabaseProperties databaseProperties; +161 +162 /** +163 * Get the value of databaseProperties. +164 * +165 * @return the value of databaseProperties +166 */ +167 public DatabaseProperties getDatabaseProperties() { +168 return databaseProperties; +169 } +170 +171 /** +172 * Searches the CPE entries in the database and retrieves all entries for a given vendor and product combination. The returned +173 * list will include all versions of the product that are registered in the NVD CVE data. +174 * +175 * @param vendor the identified vendor name of the dependency being analyzed +176 * @param product the identified name of the product of the dependency being analyzed +177 * @return a set of vulnerable software +178 */ +179 public Set<VulnerableSoftware> getCPEs(String vendor, String product) { +180 final Set<VulnerableSoftware> cpe = new HashSet<VulnerableSoftware>(); +181 ResultSet rs = null; +182 PreparedStatement ps = null; +183 try { +184 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_CPE_ENTRIES")); +185 ps.setString(1, vendor); +186 ps.setString(2, product); +187 rs = ps.executeQuery(); +188 +189 while (rs.next()) { +190 final VulnerableSoftware vs = new VulnerableSoftware(); +191 vs.setCpe(rs.getString(1)); +192 cpe.add(vs); +193 } +194 } catch (SQLException ex) { +195 LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details."); +196 LOGGER.debug("", ex); +197 } finally { +198 DBUtils.closeResultSet(rs); +199 DBUtils.closeStatement(ps); +200 } +201 return cpe; +202 } +203 +204 /** +205 * Returns the entire list of vendor/product combinations. +206 * +207 * @return the entire list of vendor/product combinations +208 * @throws DatabaseException thrown when there is an error retrieving the data from the DB +209 */ +210 public Set<Pair<String, String>> getVendorProductList() throws DatabaseException { +211 final Set<Pair<String, String>> data = new HashSet<Pair<String, String>>(); +212 ResultSet rs = null; +213 PreparedStatement ps = null; +214 try { +215 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_VENDOR_PRODUCT_LIST")); +216 rs = ps.executeQuery(); +217 while (rs.next()) { +218 data.add(new Pair<String, String>(rs.getString(1), rs.getString(2))); +219 } +220 } catch (SQLException ex) { +221 final String msg = "An unexpected SQL Exception occurred; please see the verbose log for more details."; +222 throw new DatabaseException(msg, ex); +223 } finally { +224 DBUtils.closeResultSet(rs); +225 DBUtils.closeStatement(ps); +226 } +227 return data; +228 } +229 +230 /** +231 * Returns a set of properties. +232 * +233 * @return the properties from the database +234 */ +235 Properties getProperties() { +236 final Properties prop = new Properties(); +237 PreparedStatement ps = null; +238 ResultSet rs = null; +239 try { +240 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_PROPERTIES")); +241 rs = ps.executeQuery(); +242 while (rs.next()) { +243 prop.setProperty(rs.getString(1), rs.getString(2)); +244 } +245 } catch (SQLException ex) { +246 LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details."); +247 LOGGER.debug("", ex); +248 } finally { +249 DBUtils.closeStatement(ps); +250 DBUtils.closeResultSet(rs); +251 } +252 return prop; +253 } +254 +255 /** +256 * Saves a set of properties to the database. +257 * +258 * @param props a collection of properties +259 */ +260 void saveProperties(Properties props) { +261 PreparedStatement updateProperty = null; +262 PreparedStatement insertProperty = null; +263 try { +264 try { +265 updateProperty = getConnection().prepareStatement(statementBundle.getString("UPDATE_PROPERTY")); +266 insertProperty = getConnection().prepareStatement(statementBundle.getString("INSERT_PROPERTY")); +267 } catch (SQLException ex) { +268 LOGGER.warn("Unable to save properties to the database"); +269 LOGGER.debug("Unable to save properties to the database", ex); +270 return; +271 } +272 for (Entry<Object, Object> entry : props.entrySet()) { +273 final String key = entry.getKey().toString(); +274 final String value = entry.getValue().toString(); +275 try { +276 updateProperty.setString(1, value); +277 updateProperty.setString(2, key); +278 if (updateProperty.executeUpdate() == 0) { +279 insertProperty.setString(1, key); +280 insertProperty.setString(2, value); +281 } +282 } catch (SQLException ex) { +283 LOGGER.warn("Unable to save property '{}' with a value of '{}' to the database", key, value); +284 LOGGER.debug("", ex); +285 } +286 } +287 } finally { +288 DBUtils.closeStatement(updateProperty); +289 DBUtils.closeStatement(insertProperty); +290 } +291 } +292 +293 /** +294 * Saves a property to the database. +295 * +296 * @param key the property key +297 * @param value the property value +298 */ +299 void saveProperty(String key, String value) { +300 PreparedStatement updateProperty = null; +301 PreparedStatement insertProperty = null; +302 try { +303 try { +304 updateProperty = getConnection().prepareStatement(statementBundle.getString("UPDATE_PROPERTY")); +305 } catch (SQLException ex) { +306 LOGGER.warn("Unable to save properties to the database"); +307 LOGGER.debug("Unable to save properties to the database", ex); +308 return; +309 } +310 try { +311 updateProperty.setString(1, value); +312 updateProperty.setString(2, key); +313 if (updateProperty.executeUpdate() == 0) { +314 try { +315 insertProperty = getConnection().prepareStatement(statementBundle.getString("INSERT_PROPERTY")); +316 } catch (SQLException ex) { +317 LOGGER.warn("Unable to save properties to the database"); +318 LOGGER.debug("Unable to save properties to the database", ex); +319 return; +320 } +321 insertProperty.setString(1, key); +322 insertProperty.setString(2, value); +323 insertProperty.execute(); +324 } +325 } catch (SQLException ex) { +326 LOGGER.warn("Unable to save property '{}' with a value of '{}' to the database", key, value); +327 LOGGER.debug("", ex); +328 } +329 } finally { +330 DBUtils.closeStatement(updateProperty); +331 DBUtils.closeStatement(insertProperty); +332 } +333 } +334 +335 /** +336 * Retrieves the vulnerabilities associated with the specified CPE. +337 * +338 * @param cpeStr the CPE name +339 * @return a list of Vulnerabilities +340 * @throws DatabaseException thrown if there is an exception retrieving data +341 */ +342 public List<Vulnerability> getVulnerabilities(String cpeStr) throws DatabaseException { +343 ResultSet rs = null; +344 final VulnerableSoftware cpe = new VulnerableSoftware(); +345 try { +346 cpe.parseName(cpeStr); +347 } catch (UnsupportedEncodingException ex) { +348 LOGGER.trace("", ex); +349 } +350 final DependencyVersion detectedVersion = parseDependencyVersion(cpe); +351 final List<Vulnerability> vulnerabilities = new ArrayList<Vulnerability>(); +352 +353 PreparedStatement ps; +354 try { +355 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_CVE_FROM_SOFTWARE")); +356 ps.setString(1, cpe.getVendor()); +357 ps.setString(2, cpe.getProduct()); +358 rs = ps.executeQuery(); +359 String currentCVE = ""; +360 +361 final Map<String, Boolean> vulnSoftware = new HashMap<String, Boolean>(); +362 while (rs.next()) { +363 final String cveId = rs.getString(1); +364 if (!currentCVE.equals(cveId)) { //check for match and add +365 final Entry<String, Boolean> matchedCPE = getMatchingSoftware(vulnSoftware, cpe.getVendor(), cpe.getProduct(), detectedVersion); +366 if (matchedCPE != null) { +367 final Vulnerability v = getVulnerability(currentCVE); +368 v.setMatchedCPE(matchedCPE.getKey(), matchedCPE.getValue() ? "Y" : null); +369 vulnerabilities.add(v); +370 } +371 vulnSoftware.clear(); +372 currentCVE = cveId; +373 } +374 +375 final String cpeId = rs.getString(2); +376 final String previous = rs.getString(3); +377 final Boolean p = previous != null && !previous.isEmpty(); +378 vulnSoftware.put(cpeId, p); +379 } +380 //remember to process the last set of CVE/CPE entries +381 final Entry<String, Boolean> matchedCPE = getMatchingSoftware(vulnSoftware, cpe.getVendor(), cpe.getProduct(), detectedVersion); +382 if (matchedCPE != null) { +383 final Vulnerability v = getVulnerability(currentCVE); +384 v.setMatchedCPE(matchedCPE.getKey(), matchedCPE.getValue() ? "Y" : null); +385 vulnerabilities.add(v); +386 } +387 DBUtils.closeResultSet(rs); +388 DBUtils.closeStatement(ps); +389 } catch (SQLException ex) { +390 throw new DatabaseException("Exception retrieving vulnerability for " + cpeStr, ex); +391 } finally { 392 DBUtils.closeResultSet(rs); -393 DBUtils.closeStatement(ps); -394 } catch (SQLException ex) { -395 throw new DatabaseException("Exception retrieving vulnerability for " + cpeStr, ex); -396 } finally { -397 DBUtils.closeResultSet(rs); -398 } -399 return vulnerabilities; -400 } -401 -402 /** -403 * Gets a vulnerability for the provided CVE. -404 * -405 * @param cve the CVE to lookup -406 * @return a vulnerability object -407 * @throws DatabaseException if an exception occurs -408 */ -409 private Vulnerability getVulnerability(String cve) throws DatabaseException { -410 PreparedStatement psV = null; -411 PreparedStatement psR = null; -412 PreparedStatement psS = null; -413 ResultSet rsV = null; -414 ResultSet rsR = null; -415 ResultSet rsS = null; -416 Vulnerability vuln = null; -417 try { -418 psV = getConnection().prepareStatement(statementBundle.getString("SELECT_VULNERABILITY")); -419 psV.setString(1, cve); -420 rsV = psV.executeQuery(); -421 if (rsV.next()) { -422 vuln = new Vulnerability(); -423 vuln.setName(cve); -424 vuln.setDescription(rsV.getString(2)); -425 String cwe = rsV.getString(3); -426 if (cwe != null) { -427 final String name = CweDB.getCweName(cwe); -428 if (name != null) { -429 cwe += " " + name; -430 } -431 } -432 final int cveId = rsV.getInt(1); -433 vuln.setCwe(cwe); -434 vuln.setCvssScore(rsV.getFloat(4)); -435 vuln.setCvssAccessVector(rsV.getString(5)); -436 vuln.setCvssAccessComplexity(rsV.getString(6)); -437 vuln.setCvssAuthentication(rsV.getString(7)); -438 vuln.setCvssConfidentialityImpact(rsV.getString(8)); -439 vuln.setCvssIntegrityImpact(rsV.getString(9)); -440 vuln.setCvssAvailabilityImpact(rsV.getString(10)); -441 -442 psR = getConnection().prepareStatement(statementBundle.getString("SELECT_REFERENCES")); -443 psR.setInt(1, cveId); -444 rsR = psR.executeQuery(); -445 while (rsR.next()) { -446 vuln.addReference(rsR.getString(1), rsR.getString(2), rsR.getString(3)); -447 } -448 psS = getConnection().prepareStatement(statementBundle.getString("SELECT_SOFTWARE")); -449 psS.setInt(1, cveId); -450 rsS = psS.executeQuery(); -451 while (rsS.next()) { -452 final String cpe = rsS.getString(1); -453 final String prevVersion = rsS.getString(2); -454 if (prevVersion == null) { -455 vuln.addVulnerableSoftware(cpe); -456 } else { -457 vuln.addVulnerableSoftware(cpe, prevVersion); -458 } -459 } -460 } -461 } catch (SQLException ex) { -462 throw new DatabaseException("Error retrieving " + cve, ex); -463 } finally { -464 DBUtils.closeResultSet(rsV); -465 DBUtils.closeResultSet(rsR); -466 DBUtils.closeResultSet(rsS); -467 DBUtils.closeStatement(psV); -468 DBUtils.closeStatement(psR); -469 DBUtils.closeStatement(psS); -470 } -471 return vuln; -472 } -473 -474 /** -475 * Updates the vulnerability within the database. If the vulnerability does not exist it will be added. -476 * -477 * @param vuln the vulnerability to add to the database -478 * @throws DatabaseException is thrown if the database -479 */ -480 public void updateVulnerability(Vulnerability vuln) throws DatabaseException { -481 PreparedStatement selectVulnerabilityId = null; -482 PreparedStatement deleteVulnerability = null; -483 PreparedStatement deleteReferences = null; -484 PreparedStatement deleteSoftware = null; -485 PreparedStatement updateVulnerability = null; -486 PreparedStatement insertVulnerability = null; -487 PreparedStatement insertReference = null; -488 PreparedStatement selectCpeId = null; -489 PreparedStatement insertCpe = null; -490 PreparedStatement insertSoftware = null; -491 -492 try { -493 selectVulnerabilityId = getConnection().prepareStatement(statementBundle.getString("SELECT_VULNERABILITY_ID")); -494 deleteVulnerability = getConnection().prepareStatement(statementBundle.getString("DELETE_VULNERABILITY")); -495 deleteReferences = getConnection().prepareStatement(statementBundle.getString("DELETE_REFERENCE")); -496 deleteSoftware = getConnection().prepareStatement(statementBundle.getString("DELETE_SOFTWARE")); -497 updateVulnerability = getConnection().prepareStatement(statementBundle.getString("UPDATE_VULNERABILITY")); -498 insertVulnerability = getConnection().prepareStatement(statementBundle.getString("INSERT_VULNERABILITY"), -499 Statement.RETURN_GENERATED_KEYS); -500 insertReference = getConnection().prepareStatement(statementBundle.getString("INSERT_REFERENCE")); -501 selectCpeId = getConnection().prepareStatement(statementBundle.getString("SELECT_CPE_ID")); -502 insertCpe = getConnection().prepareStatement(statementBundle.getString("INSERT_CPE"), -503 Statement.RETURN_GENERATED_KEYS); -504 insertSoftware = getConnection().prepareStatement(statementBundle.getString("INSERT_SOFTWARE")); -505 int vulnerabilityId = 0; -506 selectVulnerabilityId.setString(1, vuln.getName()); -507 ResultSet rs = selectVulnerabilityId.executeQuery(); -508 if (rs.next()) { -509 vulnerabilityId = rs.getInt(1); -510 // first delete any existing vulnerability info. We don't know what was updated. yes, slower but atm easier. -511 deleteReferences.setInt(1, vulnerabilityId); -512 deleteReferences.execute(); -513 deleteSoftware.setInt(1, vulnerabilityId); -514 deleteSoftware.execute(); -515 } -516 DBUtils.closeResultSet(rs); -517 rs = null; -518 if (vulnerabilityId != 0) { -519 if (vuln.getDescription().contains("** REJECT **")) { -520 deleteVulnerability.setInt(1, vulnerabilityId); -521 deleteVulnerability.executeUpdate(); -522 } else { -523 updateVulnerability.setString(1, vuln.getDescription()); -524 updateVulnerability.setString(2, vuln.getCwe()); -525 updateVulnerability.setFloat(3, vuln.getCvssScore()); -526 updateVulnerability.setString(4, vuln.getCvssAccessVector()); -527 updateVulnerability.setString(5, vuln.getCvssAccessComplexity()); -528 updateVulnerability.setString(6, vuln.getCvssAuthentication()); -529 updateVulnerability.setString(7, vuln.getCvssConfidentialityImpact()); -530 updateVulnerability.setString(8, vuln.getCvssIntegrityImpact()); -531 updateVulnerability.setString(9, vuln.getCvssAvailabilityImpact()); -532 updateVulnerability.setInt(10, vulnerabilityId); -533 updateVulnerability.executeUpdate(); -534 } -535 } else { -536 insertVulnerability.setString(1, vuln.getName()); -537 insertVulnerability.setString(2, vuln.getDescription()); -538 insertVulnerability.setString(3, vuln.getCwe()); -539 insertVulnerability.setFloat(4, vuln.getCvssScore()); -540 insertVulnerability.setString(5, vuln.getCvssAccessVector()); -541 insertVulnerability.setString(6, vuln.getCvssAccessComplexity()); -542 insertVulnerability.setString(7, vuln.getCvssAuthentication()); -543 insertVulnerability.setString(8, vuln.getCvssConfidentialityImpact()); -544 insertVulnerability.setString(9, vuln.getCvssIntegrityImpact()); -545 insertVulnerability.setString(10, vuln.getCvssAvailabilityImpact()); -546 insertVulnerability.execute(); -547 try { -548 rs = insertVulnerability.getGeneratedKeys(); -549 rs.next(); -550 vulnerabilityId = rs.getInt(1); -551 } catch (SQLException ex) { -552 final String msg = String.format("Unable to retrieve id for new vulnerability for '%s'", vuln.getName()); -553 throw new DatabaseException(msg, ex); -554 } finally { -555 DBUtils.closeResultSet(rs); -556 rs = null; -557 } -558 } -559 insertReference.setInt(1, vulnerabilityId); -560 for (Reference r : vuln.getReferences()) { -561 insertReference.setString(2, r.getName()); -562 insertReference.setString(3, r.getUrl()); -563 insertReference.setString(4, r.getSource()); -564 insertReference.execute(); -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 if (s.getPreviousVersion() == null) { -595 insertSoftware.setNull(3, java.sql.Types.VARCHAR); -596 } else { -597 insertSoftware.setString(3, s.getPreviousVersion()); -598 } -599 insertSoftware.execute(); -600 } -601 -602 } catch (SQLException ex) { -603 final String msg = String.format("Error updating '%s'", vuln.getName()); -604 LOGGER.log(Level.FINE, null, ex); -605 throw new DatabaseException(msg, ex); -606 } finally { -607 DBUtils.closeStatement(selectVulnerabilityId); -608 DBUtils.closeStatement(deleteReferences); -609 DBUtils.closeStatement(deleteSoftware); -610 DBUtils.closeStatement(updateVulnerability); -611 DBUtils.closeStatement(deleteVulnerability); -612 DBUtils.closeStatement(insertVulnerability); -613 DBUtils.closeStatement(insertReference); -614 DBUtils.closeStatement(selectCpeId); -615 DBUtils.closeStatement(insertCpe); -616 DBUtils.closeStatement(insertSoftware); -617 } -618 } -619 -620 /** -621 * Checks to see if data exists so that analysis can be performed. -622 * -623 * @return <code>true</code> if data exists; otherwise <code>false</code> -624 */ -625 public boolean dataExists() { -626 Statement cs = null; -627 ResultSet rs = null; -628 try { -629 cs = conn.createStatement(); -630 rs = cs.executeQuery("SELECT COUNT(*) records FROM cpeEntry"); -631 if (rs.next()) { -632 if (rs.getInt(1) > 0) { -633 return true; -634 } -635 } -636 } catch (SQLException ex) { -637 String dd; -638 try { -639 dd = Settings.getDataDirectory().getAbsolutePath(); -640 } catch (IOException ex1) { -641 dd = Settings.getString(Settings.KEYS.DATA_DIRECTORY); -642 } -643 final String msg = String.format("Unable to access the local database.%n%nEnsure that '%s' is a writable directory. " -644 + "If the problem persist try deleting the files in '%s' and running %s again. If the problem continues, please " -645 + "create a log file (see documentation at http://jeremylong.github.io/DependencyCheck/) and open a ticket at " -646 + "https://github.com/jeremylong/DependencyCheck/issues and include the log file.%n%n", -647 dd, dd, Settings.getString(Settings.KEYS.APPLICATION_VAME)); -648 LOGGER.log(Level.SEVERE, msg); -649 LOGGER.log(Level.FINE, "", ex); -650 } finally { -651 DBUtils.closeResultSet(rs); -652 DBUtils.closeStatement(cs); -653 } -654 return false; -655 } -656 -657 /** -658 * It is possible that orphaned rows may be generated during database updates. This should be called after all updates have -659 * been completed to ensure orphan entries are removed. -660 */ -661 public void cleanupDatabase() { -662 PreparedStatement ps = null; -663 try { -664 ps = getConnection().prepareStatement(statementBundle.getString("CLEANUP_ORPHANS")); -665 if (ps != null) { -666 ps.executeUpdate(); -667 } -668 } catch (SQLException ex) { -669 final String msg = "An unexpected SQL Exception occurred; please see the verbose log for more details."; -670 LOGGER.log(Level.SEVERE, msg); -671 LOGGER.log(Level.FINE, null, ex); -672 } finally { -673 DBUtils.closeStatement(ps); -674 } -675 } -676 -677 /** -678 * Determines if the given identifiedVersion is affected by the given cpeId and previous version flag. A non-null, non-empty -679 * string passed to the previous version argument indicates that all previous versions are affected. -680 * -681 * @param vendor the vendor of the dependency being analyzed -682 * @param product the product name of the dependency being analyzed -683 * @param vulnerableSoftware a map of the vulnerable software with a boolean indicating if all previous versions are affected -684 * @param identifiedVersion the identified version of the dependency being analyzed -685 * @return true if the identified version is affected, otherwise false -686 */ -687 Entry<String, Boolean> getMatchingSoftware(Map<String, Boolean> vulnerableSoftware, String vendor, String product, -688 DependencyVersion identifiedVersion) { -689 -690 final boolean isVersionTwoADifferentProduct = "apache".equals(vendor) && "struts".equals(product); -691 -692 final Set<String> majorVersionsAffectingAllPrevious = new HashSet<String>(); -693 final boolean matchesAnyPrevious = identifiedVersion == null || "-".equals(identifiedVersion.toString()); -694 String majorVersionMatch = null; -695 for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) { -696 final DependencyVersion v = parseDependencyVersion(entry.getKey()); -697 if (v == null || "-".equals(v.toString())) { //all versions -698 return entry; -699 } -700 if (entry.getValue()) { -701 if (matchesAnyPrevious) { -702 return entry; -703 } -704 if (identifiedVersion != null && identifiedVersion.getVersionParts().get(0).equals(v.getVersionParts().get(0))) { -705 majorVersionMatch = v.getVersionParts().get(0); -706 } -707 majorVersionsAffectingAllPrevious.add(v.getVersionParts().get(0)); -708 } -709 } -710 if (matchesAnyPrevious) { -711 return null; -712 } -713 -714 final boolean canSkipVersions = majorVersionMatch != null && majorVersionsAffectingAllPrevious.size() > 1; -715 //yes, we are iterating over this twice. The first time we are skipping versions those that affect all versions -716 //then later we process those that affect all versions. This could be done with sorting... -717 for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) { -718 if (!entry.getValue()) { -719 final DependencyVersion v = parseDependencyVersion(entry.getKey()); -720 //this can't dereference a null 'majorVersionMatch' as canSkipVersions accounts for this. -721 if (canSkipVersions && !majorVersionMatch.equals(v.getVersionParts().get(0))) { -722 continue; -723 } -724 //this can't dereference a null 'identifiedVersion' because if it was null we would have exited -725 //in the above loop or just after loop (if matchesAnyPrevious return null). -726 if (identifiedVersion.equals(v)) { -727 return entry; -728 } -729 } -730 } -731 for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) { -732 if (entry.getValue()) { -733 final DependencyVersion v = parseDependencyVersion(entry.getKey()); -734 //this can't dereference a null 'majorVersionMatch' as canSkipVersions accounts for this. -735 if (canSkipVersions && !majorVersionMatch.equals(v.getVersionParts().get(0))) { -736 continue; -737 } -738 //this can't dereference a null 'identifiedVersion' because if it was null we would have exited -739 //in the above loop or just after loop (if matchesAnyPrevious return null). -740 if (entry.getValue() && identifiedVersion.compareTo(v) <= 0) { -741 if (!(isVersionTwoADifferentProduct && !identifiedVersion.getVersionParts().get(0).equals(v.getVersionParts().get(0)))) { -742 return entry; -743 } -744 } -745 } -746 } -747 return null; -748 } -749 -750 /** -751 * Parses the version (including revision) from a CPE identifier. If no version is identified then a '-' is returned. -752 * -753 * @param cpeStr a cpe identifier -754 * @return a dependency version -755 */ -756 private DependencyVersion parseDependencyVersion(String cpeStr) { -757 final VulnerableSoftware cpe = new VulnerableSoftware(); -758 try { -759 cpe.parseName(cpeStr); -760 } catch (UnsupportedEncodingException ex) { -761 //never going to happen. -762 LOGGER.log(Level.FINEST, null, ex); -763 } -764 return parseDependencyVersion(cpe); -765 } -766 -767 /** -768 * Takes a CPE and parses out the version number. If no version is identified then a '-' is returned. -769 * -770 * @param cpe a cpe object -771 * @return a dependency version -772 */ -773 private DependencyVersion parseDependencyVersion(VulnerableSoftware cpe) { -774 DependencyVersion cpeVersion; -775 if (cpe.getVersion() != null && !cpe.getVersion().isEmpty()) { -776 String versionText; -777 if (cpe.getRevision() != null && !cpe.getRevision().isEmpty()) { -778 versionText = String.format("%s.%s", cpe.getVersion(), cpe.getRevision()); -779 } else { -780 versionText = cpe.getVersion(); -781 } -782 cpeVersion = DependencyVersionUtil.parseVersion(versionText); -783 } else { -784 cpeVersion = new DependencyVersion("-"); -785 } -786 return cpeVersion; -787 } -788 } +393 } +394 return vulnerabilities; +395 } +396 +397 /** +398 * Gets a vulnerability for the provided CVE. +399 * +400 * @param cve the CVE to lookup +401 * @return a vulnerability object +402 * @throws DatabaseException if an exception occurs +403 */ +404 private Vulnerability getVulnerability(String cve) throws DatabaseException { +405 PreparedStatement psV = null; +406 PreparedStatement psR = null; +407 PreparedStatement psS = null; +408 ResultSet rsV = null; +409 ResultSet rsR = null; +410 ResultSet rsS = null; +411 Vulnerability vuln = null; +412 try { +413 psV = getConnection().prepareStatement(statementBundle.getString("SELECT_VULNERABILITY")); +414 psV.setString(1, cve); +415 rsV = psV.executeQuery(); +416 if (rsV.next()) { +417 vuln = new Vulnerability(); +418 vuln.setName(cve); +419 vuln.setDescription(rsV.getString(2)); +420 String cwe = rsV.getString(3); +421 if (cwe != null) { +422 final String name = CweDB.getCweName(cwe); +423 if (name != null) { +424 cwe += " " + name; +425 } +426 } +427 final int cveId = rsV.getInt(1); +428 vuln.setCwe(cwe); +429 vuln.setCvssScore(rsV.getFloat(4)); +430 vuln.setCvssAccessVector(rsV.getString(5)); +431 vuln.setCvssAccessComplexity(rsV.getString(6)); +432 vuln.setCvssAuthentication(rsV.getString(7)); +433 vuln.setCvssConfidentialityImpact(rsV.getString(8)); +434 vuln.setCvssIntegrityImpact(rsV.getString(9)); +435 vuln.setCvssAvailabilityImpact(rsV.getString(10)); +436 +437 psR = getConnection().prepareStatement(statementBundle.getString("SELECT_REFERENCES")); +438 psR.setInt(1, cveId); +439 rsR = psR.executeQuery(); +440 while (rsR.next()) { +441 vuln.addReference(rsR.getString(1), rsR.getString(2), rsR.getString(3)); +442 } +443 psS = getConnection().prepareStatement(statementBundle.getString("SELECT_SOFTWARE")); +444 psS.setInt(1, cveId); +445 rsS = psS.executeQuery(); +446 while (rsS.next()) { +447 final String cpe = rsS.getString(1); +448 final String prevVersion = rsS.getString(2); +449 if (prevVersion == null) { +450 vuln.addVulnerableSoftware(cpe); +451 } else { +452 vuln.addVulnerableSoftware(cpe, prevVersion); +453 } +454 } +455 } +456 } catch (SQLException ex) { +457 throw new DatabaseException("Error retrieving " + cve, ex); +458 } finally { +459 DBUtils.closeResultSet(rsV); +460 DBUtils.closeResultSet(rsR); +461 DBUtils.closeResultSet(rsS); +462 DBUtils.closeStatement(psV); +463 DBUtils.closeStatement(psR); +464 DBUtils.closeStatement(psS); +465 } +466 return vuln; +467 } +468 +469 /** +470 * Updates the vulnerability within the database. If the vulnerability does not exist it will be added. +471 * +472 * @param vuln the vulnerability to add to the database +473 * @throws DatabaseException is thrown if the database +474 */ +475 public void updateVulnerability(Vulnerability vuln) throws DatabaseException { +476 PreparedStatement selectVulnerabilityId = null; +477 PreparedStatement deleteVulnerability = null; +478 PreparedStatement deleteReferences = null; +479 PreparedStatement deleteSoftware = null; +480 PreparedStatement updateVulnerability = null; +481 PreparedStatement insertVulnerability = null; +482 PreparedStatement insertReference = null; +483 PreparedStatement selectCpeId = null; +484 PreparedStatement insertCpe = null; +485 PreparedStatement insertSoftware = null; +486 +487 try { +488 selectVulnerabilityId = getConnection().prepareStatement(statementBundle.getString("SELECT_VULNERABILITY_ID")); +489 deleteVulnerability = getConnection().prepareStatement(statementBundle.getString("DELETE_VULNERABILITY")); +490 deleteReferences = getConnection().prepareStatement(statementBundle.getString("DELETE_REFERENCE")); +491 deleteSoftware = getConnection().prepareStatement(statementBundle.getString("DELETE_SOFTWARE")); +492 updateVulnerability = getConnection().prepareStatement(statementBundle.getString("UPDATE_VULNERABILITY")); +493 String ids[] = {"id"}; +494 insertVulnerability = getConnection().prepareStatement(statementBundle.getString("INSERT_VULNERABILITY"), +495 //Statement.RETURN_GENERATED_KEYS); +496 ids); +497 insertReference = getConnection().prepareStatement(statementBundle.getString("INSERT_REFERENCE")); +498 selectCpeId = getConnection().prepareStatement(statementBundle.getString("SELECT_CPE_ID")); +499 insertCpe = getConnection().prepareStatement(statementBundle.getString("INSERT_CPE"), +500 //Statement.RETURN_GENERATED_KEYS); +501 ids); +502 insertSoftware = getConnection().prepareStatement(statementBundle.getString("INSERT_SOFTWARE")); +503 int vulnerabilityId = 0; +504 selectVulnerabilityId.setString(1, vuln.getName()); +505 ResultSet rs = selectVulnerabilityId.executeQuery(); +506 if (rs.next()) { +507 vulnerabilityId = rs.getInt(1); +508 // first delete any existing vulnerability info. We don't know what was updated. yes, slower but atm easier. +509 deleteReferences.setInt(1, vulnerabilityId); +510 deleteReferences.execute(); +511 deleteSoftware.setInt(1, vulnerabilityId); +512 deleteSoftware.execute(); +513 } +514 DBUtils.closeResultSet(rs); +515 rs = null; +516 if (vulnerabilityId != 0) { +517 if (vuln.getDescription().contains("** REJECT **")) { +518 deleteVulnerability.setInt(1, vulnerabilityId); +519 deleteVulnerability.executeUpdate(); +520 } else { +521 updateVulnerability.setString(1, vuln.getDescription()); +522 updateVulnerability.setString(2, vuln.getCwe()); +523 updateVulnerability.setFloat(3, vuln.getCvssScore()); +524 updateVulnerability.setString(4, vuln.getCvssAccessVector()); +525 updateVulnerability.setString(5, vuln.getCvssAccessComplexity()); +526 updateVulnerability.setString(6, vuln.getCvssAuthentication()); +527 updateVulnerability.setString(7, vuln.getCvssConfidentialityImpact()); +528 updateVulnerability.setString(8, vuln.getCvssIntegrityImpact()); +529 updateVulnerability.setString(9, vuln.getCvssAvailabilityImpact()); +530 updateVulnerability.setInt(10, vulnerabilityId); +531 updateVulnerability.executeUpdate(); +532 } +533 } else { +534 insertVulnerability.setString(1, vuln.getName()); +535 insertVulnerability.setString(2, vuln.getDescription()); +536 insertVulnerability.setString(3, vuln.getCwe()); +537 insertVulnerability.setFloat(4, vuln.getCvssScore()); +538 insertVulnerability.setString(5, vuln.getCvssAccessVector()); +539 insertVulnerability.setString(6, vuln.getCvssAccessComplexity()); +540 insertVulnerability.setString(7, vuln.getCvssAuthentication()); +541 insertVulnerability.setString(8, vuln.getCvssConfidentialityImpact()); +542 insertVulnerability.setString(9, vuln.getCvssIntegrityImpact()); +543 insertVulnerability.setString(10, vuln.getCvssAvailabilityImpact()); +544 insertVulnerability.execute(); +545 try { +546 rs = insertVulnerability.getGeneratedKeys(); +547 rs.next(); +548 vulnerabilityId = rs.getInt(1); +549 } catch (SQLException ex) { +550 final String msg = String.format("Unable to retrieve id for new vulnerability for '%s'", vuln.getName()); +551 throw new DatabaseException(msg, ex); +552 } finally { +553 DBUtils.closeResultSet(rs); +554 rs = null; +555 } +556 } +557 insertReference.setInt(1, vulnerabilityId); +558 for (Reference r : vuln.getReferences()) { +559 insertReference.setString(2, r.getName()); +560 insertReference.setString(3, r.getUrl()); +561 insertReference.setString(4, r.getSource()); +562 insertReference.execute(); +563 } +564 for (VulnerableSoftware s : vuln.getVulnerableSoftware()) { +565 int cpeProductId = 0; +566 selectCpeId.setString(1, s.getName()); +567 try { +568 rs = selectCpeId.executeQuery(); +569 if (rs.next()) { +570 cpeProductId = rs.getInt(1); +571 } +572 } catch (SQLException ex) { +573 throw new DatabaseException("Unable to get primary key for new cpe: " + s.getName(), ex); +574 } finally { +575 DBUtils.closeResultSet(rs); +576 rs = null; +577 } +578 +579 if (cpeProductId == 0) { +580 insertCpe.setString(1, s.getName()); +581 insertCpe.setString(2, s.getVendor()); +582 insertCpe.setString(3, s.getProduct()); +583 insertCpe.executeUpdate(); +584 cpeProductId = DBUtils.getGeneratedKey(insertCpe); +585 } +586 if (cpeProductId == 0) { +587 throw new DatabaseException("Unable to retrieve cpeProductId - no data returned"); +588 } +589 +590 insertSoftware.setInt(1, vulnerabilityId); +591 insertSoftware.setInt(2, cpeProductId); +592 if (s.getPreviousVersion() == null) { +593 insertSoftware.setNull(3, java.sql.Types.VARCHAR); +594 } else { +595 insertSoftware.setString(3, s.getPreviousVersion()); +596 } +597 insertSoftware.execute(); +598 } +599 +600 } catch (SQLException ex) { +601 final String msg = String.format("Error updating '%s'", vuln.getName()); +602 LOGGER.debug("", ex); +603 throw new DatabaseException(msg, ex); +604 } finally { +605 DBUtils.closeStatement(selectVulnerabilityId); +606 DBUtils.closeStatement(deleteReferences); +607 DBUtils.closeStatement(deleteSoftware); +608 DBUtils.closeStatement(updateVulnerability); +609 DBUtils.closeStatement(deleteVulnerability); +610 DBUtils.closeStatement(insertVulnerability); +611 DBUtils.closeStatement(insertReference); +612 DBUtils.closeStatement(selectCpeId); +613 DBUtils.closeStatement(insertCpe); +614 DBUtils.closeStatement(insertSoftware); +615 } +616 } +617 +618 /** +619 * Checks to see if data exists so that analysis can be performed. +620 * +621 * @return <code>true</code> if data exists; otherwise <code>false</code> +622 */ +623 public boolean dataExists() { +624 Statement cs = null; +625 ResultSet rs = null; +626 try { +627 cs = conn.createStatement(); +628 rs = cs.executeQuery("SELECT COUNT(*) records FROM cpeEntry"); +629 if (rs.next()) { +630 if (rs.getInt(1) > 0) { +631 return true; +632 } +633 } +634 } catch (SQLException ex) { +635 String dd; +636 try { +637 dd = Settings.getDataDirectory().getAbsolutePath(); +638 } catch (IOException ex1) { +639 dd = Settings.getString(Settings.KEYS.DATA_DIRECTORY); +640 } +641 LOGGER.error("Unable to access the local database.\n\nEnsure that '{}' is a writable directory. " +642 + "If the problem persist try deleting the files in '{}' and running {} again. If the problem continues, please " +643 + "create a log file (see documentation at http://jeremylong.github.io/DependencyCheck/) and open a ticket at " +644 + "https://github.com/jeremylong/DependencyCheck/issues and include the log file.\n\n", +645 dd, dd, Settings.getString(Settings.KEYS.APPLICATION_VAME)); +646 LOGGER.debug("", ex); +647 } finally { +648 DBUtils.closeResultSet(rs); +649 DBUtils.closeStatement(cs); +650 } +651 return false; +652 } +653 +654 /** +655 * It is possible that orphaned rows may be generated during database updates. This should be called after all updates have +656 * been completed to ensure orphan entries are removed. +657 */ +658 public void cleanupDatabase() { +659 PreparedStatement ps = null; +660 try { +661 ps = getConnection().prepareStatement(statementBundle.getString("CLEANUP_ORPHANS")); +662 if (ps != null) { +663 ps.executeUpdate(); +664 } +665 } catch (SQLException ex) { +666 LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details."); +667 LOGGER.debug("", ex); +668 } finally { +669 DBUtils.closeStatement(ps); +670 } +671 } +672 +673 /** +674 * Determines if the given identifiedVersion is affected by the given cpeId and previous version flag. A non-null, non-empty +675 * string passed to the previous version argument indicates that all previous versions are affected. +676 * +677 * @param vendor the vendor of the dependency being analyzed +678 * @param product the product name of the dependency being analyzed +679 * @param vulnerableSoftware a map of the vulnerable software with a boolean indicating if all previous versions are affected +680 * @param identifiedVersion the identified version of the dependency being analyzed +681 * @return true if the identified version is affected, otherwise false +682 */ +683 Entry<String, Boolean> getMatchingSoftware(Map<String, Boolean> vulnerableSoftware, String vendor, String product, +684 DependencyVersion identifiedVersion) { +685 +686 final boolean isVersionTwoADifferentProduct = "apache".equals(vendor) && "struts".equals(product); +687 +688 final Set<String> majorVersionsAffectingAllPrevious = new HashSet<String>(); +689 final boolean matchesAnyPrevious = identifiedVersion == null || "-".equals(identifiedVersion.toString()); +690 String majorVersionMatch = null; +691 for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) { +692 final DependencyVersion v = parseDependencyVersion(entry.getKey()); +693 if (v == null || "-".equals(v.toString())) { //all versions +694 return entry; +695 } +696 if (entry.getValue()) { +697 if (matchesAnyPrevious) { +698 return entry; +699 } +700 if (identifiedVersion != null && identifiedVersion.getVersionParts().get(0).equals(v.getVersionParts().get(0))) { +701 majorVersionMatch = v.getVersionParts().get(0); +702 } +703 majorVersionsAffectingAllPrevious.add(v.getVersionParts().get(0)); +704 } +705 } +706 if (matchesAnyPrevious) { +707 return null; +708 } +709 +710 final boolean canSkipVersions = majorVersionMatch != null && majorVersionsAffectingAllPrevious.size() > 1; +711 //yes, we are iterating over this twice. The first time we are skipping versions those that affect all versions +712 //then later we process those that affect all versions. This could be done with sorting... +713 for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) { +714 if (!entry.getValue()) { +715 final DependencyVersion v = parseDependencyVersion(entry.getKey()); +716 //this can't dereference a null 'majorVersionMatch' as canSkipVersions accounts for this. +717 if (canSkipVersions && !majorVersionMatch.equals(v.getVersionParts().get(0))) { +718 continue; +719 } +720 //this can't dereference a null 'identifiedVersion' because if it was null we would have exited +721 //in the above loop or just after loop (if matchesAnyPrevious return null). +722 if (identifiedVersion.equals(v)) { +723 return entry; +724 } +725 } +726 } +727 for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) { +728 if (entry.getValue()) { +729 final DependencyVersion v = parseDependencyVersion(entry.getKey()); +730 //this can't dereference a null 'majorVersionMatch' as canSkipVersions accounts for this. +731 if (canSkipVersions && !majorVersionMatch.equals(v.getVersionParts().get(0))) { +732 continue; +733 } +734 //this can't dereference a null 'identifiedVersion' because if it was null we would have exited +735 //in the above loop or just after loop (if matchesAnyPrevious return null). +736 if (entry.getValue() && identifiedVersion.compareTo(v) <= 0) { +737 if (!(isVersionTwoADifferentProduct && !identifiedVersion.getVersionParts().get(0).equals(v.getVersionParts().get(0)))) { +738 return entry; +739 } +740 } +741 } +742 } +743 return null; +744 } +745 +746 /** +747 * Parses the version (including revision) from a CPE identifier. If no version is identified then a '-' is returned. +748 * +749 * @param cpeStr a cpe identifier +750 * @return a dependency version +751 */ +752 private DependencyVersion parseDependencyVersion(String cpeStr) { +753 final VulnerableSoftware cpe = new VulnerableSoftware(); +754 try { +755 cpe.parseName(cpeStr); +756 } catch (UnsupportedEncodingException ex) { +757 //never going to happen. +758 LOGGER.trace("", ex); +759 } +760 return parseDependencyVersion(cpe); +761 } +762 +763 /** +764 * Takes a CPE and parses out the version number. If no version is identified then a '-' is returned. +765 * +766 * @param cpe a cpe object +767 * @return a dependency version +768 */ +769 private DependencyVersion parseDependencyVersion(VulnerableSoftware cpe) { +770 DependencyVersion cpeVersion; +771 if (cpe.getVersion() != null && !cpe.getVersion().isEmpty()) { +772 String versionText; +773 if (cpe.getUpdate() != null && !cpe.getUpdate().isEmpty()) { +774 versionText = String.format("%s.%s", cpe.getVersion(), cpe.getUpdate()); +775 } else { +776 versionText = cpe.getVersion(); +777 } +778 cpeVersion = DependencyVersionUtil.parseVersion(versionText); +779 } else { +780 cpeVersion = new DependencyVersion("-"); +781 } +782 return cpeVersion; +783 } +784 +785 /** +786 * Deletes unused dictionary entries from the database. +787 */ +788 public void deleteUnusedCpe() { +789 CallableStatement cs = null; +790 try { +791 cs = getConnection().prepareCall(statementBundle.getString("DELETE_UNUSED_DICT_CPE")); +792 cs.executeUpdate(); +793 } catch (SQLException ex) { +794 LOGGER.error("Unable to delete CPE dictionary entries", ex); +795 } finally { +796 DBUtils.closeStatement(cs); +797 } +798 } +799 +800 /** +801 * Merges CPE entries into the database. +802 * +803 * @param cpe the CPE identifier +804 * @param vendor the CPE vendor +805 * @param product the CPE product +806 */ +807 public void addCpe(String cpe, String vendor, String product) { +808 PreparedStatement ps = null; +809 try { +810 ps = getConnection().prepareCall(statementBundle.getString("ADD_DICT_CPE")); +811 ps.setString(1, cpe); +812 ps.setString(2, vendor); +813 ps.setString(3, product); +814 ps.executeUpdate(); +815 } catch (SQLException ex) { +816 LOGGER.error("Unable to add CPE dictionary entry", ex); +817 } finally { +818 DBUtils.closeStatement(ps); +819 } +820 } +821 }
    diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/DatabaseProperties.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/DatabaseProperties.html index 12659b571..922117e5a 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/DatabaseProperties.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/DatabaseProperties.html @@ -32,10 +32,10 @@ 24 import java.util.Map.Entry; 25 import java.util.Properties; 26 import java.util.TreeMap; -27 import java.util.logging.Level; -28 import java.util.logging.Logger; -29 import org.owasp.dependencycheck.data.update.NvdCveInfo; -30 import org.owasp.dependencycheck.data.update.exception.UpdateException; +27 import org.owasp.dependencycheck.data.update.nvd.NvdCveInfo; +28 import org.owasp.dependencycheck.data.update.exception.UpdateException; +29 import org.slf4j.Logger; +30 import org.slf4j.LoggerFactory; 31 32 /** 33 * This is a wrapper around a set of properties that are stored in the database. @@ -47,144 +47,151 @@ 39 /** 40 * The Logger. 41 */ -42 private static final Logger LOGGER = Logger.getLogger(DatabaseProperties.class.getName()); +42 private static final Logger LOGGER = LoggerFactory.getLogger(DatabaseProperties.class); 43 /** -44 * Modified key word, used as a key to store information about the modified file (i.e. the containing the last 8 -45 * days of updates).. +44 * Modified key word, used as a key to store information about the modified file (i.e. the containing the last 8 days of +45 * updates).. 46 */ 47 public static final String MODIFIED = "Modified"; 48 /** -49 * The properties file key for the last updated field - used to store the last updated time of the Modified NVD CVE -50 * xml file. -51 */ -52 public static final String LAST_UPDATED = "NVD CVE Modified"; -53 /** -54 * Stores the last updated time for each of the NVD CVE files. These timestamps should be updated if we process the -55 * modified file within 7 days of the last update. -56 */ -57 public static final String LAST_UPDATED_BASE = "NVD CVE "; -58 /** -59 * A collection of properties about the data. -60 */ -61 private Properties properties; -62 /** -63 * A reference to the database. -64 */ -65 private CveDB cveDB; -66 -67 /** -68 * Constructs a new data properties object. -69 * -70 * @param cveDB the database object holding the properties -71 */ -72 DatabaseProperties(CveDB cveDB) { -73 this.cveDB = cveDB; -74 loadProperties(); -75 } -76 -77 /** -78 * Loads the properties from the database. +49 * The properties file key for the last updated field - used to store the last updated time of the Modified NVD CVE xml file. +50 */ +51 public static final String LAST_UPDATED = "NVD CVE Modified"; +52 /** +53 * Stores the last updated time for each of the NVD CVE files. These timestamps should be updated if we process the modified +54 * file within 7 days of the last update. +55 */ +56 public static final String LAST_UPDATED_BASE = "NVD CVE "; +57 /** +58 * The key for the last time the CPE data was updated. +59 */ +60 public static final String LAST_CPE_UPDATE = "LAST_CPE_UPDATE"; +61 /** +62 * The key for the database schema version. +63 */ +64 public static final String VERSION = "version"; +65 +66 /** +67 * A collection of properties about the data. +68 */ +69 private Properties properties; +70 /** +71 * A reference to the database. +72 */ +73 private CveDB cveDB; +74 +75 /** +76 * Constructs a new data properties object. +77 * +78 * @param cveDB the database object holding the properties 79 */ -80 private void loadProperties() { -81 this.properties = cveDB.getProperties(); -82 } -83 -84 /** -85 * Returns whether or not any properties are set. -86 * -87 * @return whether or not any properties are set -88 */ -89 public boolean isEmpty() { -90 return properties == null || properties.isEmpty(); -91 } -92 -93 /** -94 * Saves the last updated information to the properties file. -95 * -96 * @param updatedValue the updated NVD CVE entry -97 * @throws UpdateException is thrown if there is an update exception -98 */ -99 public void save(NvdCveInfo updatedValue) throws UpdateException { -100 if (updatedValue == null) { -101 return; -102 } -103 save(LAST_UPDATED_BASE + updatedValue.getId(), String.valueOf(updatedValue.getTimestamp())); -104 } -105 -106 /** -107 * Saves the key value pair to the properties store. -108 * -109 * @param key the property key -110 * @param value the property value -111 * @throws UpdateException is thrown if there is an update exception -112 */ -113 public void save(String key, String value) throws UpdateException { -114 properties.put(key, value); -115 cveDB.saveProperty(key, value); -116 } -117 -118 /** -119 * Returns the property value for the given key. If the key is not contained in the underlying properties null is -120 * returned. -121 * -122 * @param key the property key -123 * @return the value of the property -124 */ -125 public String getProperty(String key) { -126 return properties.getProperty(key); -127 } -128 -129 /** -130 * Returns the property value for the given key. If the key is not contained in the underlying properties the -131 * default value is returned. -132 * -133 * @param key the property key -134 * @param defaultValue the default value -135 * @return the value of the property -136 */ -137 public String getProperty(String key, String defaultValue) { -138 return properties.getProperty(key, defaultValue); -139 } -140 -141 /** -142 * Returns the collection of Database Properties as a properties collection. -143 * -144 * @return the collection of Database Properties -145 */ -146 public Properties getProperties() { -147 return properties; -148 } -149 -150 /** -151 * Returns a map of the meta data from the database properties. This primarily contains timestamps of when the NVD -152 * CVE information was last updated. -153 * -154 * @return a map of the database meta data -155 */ -156 public Map<String, String> getMetaData() { -157 final Map<String, String> map = new TreeMap<String, String>(); -158 for (Entry<Object, Object> entry : properties.entrySet()) { -159 final String key = (String) entry.getKey(); -160 if (!"version".equals(key)) { -161 if (key.startsWith("NVD CVE ")) { -162 try { -163 final long epoch = Long.parseLong((String) entry.getValue()); -164 final Date date = new Date(epoch); -165 final DateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss"); -166 final String formatted = format.format(date); -167 map.put(key, formatted); -168 } catch (Throwable ex) { //deliberately being broad in this catch clause -169 LOGGER.log(Level.FINE, "Unable to parse timestamp from DB", ex); -170 map.put(key, (String) entry.getValue()); -171 } -172 } else { -173 map.put(key, (String) entry.getValue()); -174 } -175 } -176 } -177 return map; -178 } -179 } +80 DatabaseProperties(CveDB cveDB) { +81 this.cveDB = cveDB; +82 loadProperties(); +83 } +84 +85 /** +86 * Loads the properties from the database. +87 */ +88 private void loadProperties() { +89 this.properties = cveDB.getProperties(); +90 } +91 +92 /** +93 * Returns whether or not any properties are set. +94 * +95 * @return whether or not any properties are set +96 */ +97 public boolean isEmpty() { +98 return properties == null || properties.isEmpty(); +99 } +100 +101 /** +102 * Saves the last updated information to the properties file. +103 * +104 * @param updatedValue the updated NVD CVE entry +105 * @throws UpdateException is thrown if there is an update exception +106 */ +107 public void save(NvdCveInfo updatedValue) throws UpdateException { +108 if (updatedValue == null) { +109 return; +110 } +111 save(LAST_UPDATED_BASE + updatedValue.getId(), String.valueOf(updatedValue.getTimestamp())); +112 } +113 +114 /** +115 * Saves the key value pair to the properties store. +116 * +117 * @param key the property key +118 * @param value the property value +119 * @throws UpdateException is thrown if there is an update exception +120 */ +121 public void save(String key, String value) throws UpdateException { +122 properties.put(key, value); +123 cveDB.saveProperty(key, value); +124 } +125 +126 /** +127 * Returns the property value for the given key. If the key is not contained in the underlying properties null is returned. +128 * +129 * @param key the property key +130 * @return the value of the property +131 */ +132 public String getProperty(String key) { +133 return properties.getProperty(key); +134 } +135 +136 /** +137 * Returns the property value for the given key. If the key is not contained in the underlying properties the default value is +138 * returned. +139 * +140 * @param key the property key +141 * @param defaultValue the default value +142 * @return the value of the property +143 */ +144 public String getProperty(String key, String defaultValue) { +145 return properties.getProperty(key, defaultValue); +146 } +147 +148 /** +149 * Returns the collection of Database Properties as a properties collection. +150 * +151 * @return the collection of Database Properties +152 */ +153 public Properties getProperties() { +154 return properties; +155 } +156 +157 /** +158 * Returns a map of the meta data from the database properties. This primarily contains timestamps of when the NVD CVE +159 * information was last updated. +160 * +161 * @return a map of the database meta data +162 */ +163 public Map<String, String> getMetaData() { +164 final Map<String, String> map = new TreeMap<String, String>(); +165 for (Entry<Object, Object> entry : properties.entrySet()) { +166 final String key = (String) entry.getKey(); +167 if (!"version".equals(key)) { +168 if (key.startsWith("NVD CVE ")) { +169 try { +170 final long epoch = Long.parseLong((String) entry.getValue()); +171 final Date date = new Date(epoch); +172 final DateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss"); +173 final String formatted = format.format(date); +174 map.put(key, formatted); +175 } catch (Throwable ex) { //deliberately being broad in this catch clause +176 LOGGER.debug("Unable to parse timestamp from DB", ex); +177 map.put(key, (String) entry.getValue()); +178 } +179 } else { +180 map.put(key, (String) entry.getValue()); +181 } +182 } +183 } +184 return map; +185 } +186 }
    diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/DriverLoader.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/DriverLoader.html index 4137598f8..3385d85be 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/DriverLoader.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/DriverLoader.html @@ -25,139 +25,138 @@ 17 */ 18 package org.owasp.dependencycheck.data.nvdcve; 19 -20 import java.io.File; -21 import java.net.MalformedURLException; -22 import java.net.URL; -23 import java.net.URLClassLoader; -24 import java.security.AccessController; -25 import java.security.PrivilegedAction; -26 import java.sql.Driver; -27 import java.sql.DriverManager; -28 import java.sql.SQLException; -29 import java.util.ArrayList; -30 import java.util.List; -31 import java.util.logging.Level; -32 import java.util.logging.Logger; -33 -34 /** -35 * DriverLoader is a utility class that is used to load database drivers. -36 * -37 * @author Jeremy Long -38 */ -39 public final class DriverLoader { -40 -41 /** -42 * The logger. -43 */ -44 private static final Logger LOGGER = Logger.getLogger(DriverLoader.class.getName()); -45 -46 /** -47 * Private constructor for a utility class. -48 */ -49 private DriverLoader() { -50 } -51 -52 /** -53 * Loads the specified class using the system class loader and registers the driver with the driver manager. -54 * -55 * @param className the fully qualified name of the desired class -56 * @return the loaded Driver -57 * @throws DriverLoadException thrown if the driver cannot be loaded -58 */ -59 public static Driver load(String className) throws DriverLoadException { -60 final ClassLoader loader = DriverLoader.class.getClassLoader(); //ClassLoader.getSystemClassLoader(); -61 return load(className, loader); -62 } -63 -64 /** -65 * Loads the specified class by registering the supplied paths to the class loader and then registers the driver -66 * with the driver manager. The pathToDriver argument is added to the class loader so that an external driver can be -67 * loaded. Note, the pathToDriver can contain a semi-colon separated list of paths so any dependencies can be added -68 * as needed. If a path in the pathToDriver argument is a directory all files in the directory are added to the -69 * class path. -70 * -71 * @param className the fully qualified name of the desired class -72 * @param pathToDriver the path to the JAR file containing the driver; note, this can be a semi-colon separated list -73 * of paths -74 * @return the loaded Driver -75 * @throws DriverLoadException thrown if the driver cannot be loaded -76 */ -77 public static Driver load(String className, String pathToDriver) throws DriverLoadException { -78 final URLClassLoader parent = (URLClassLoader) ClassLoader.getSystemClassLoader(); -79 final List<URL> urls = new ArrayList<URL>(); -80 final String[] paths = pathToDriver.split(File.pathSeparator); -81 for (String path : paths) { -82 final File file = new File(path); -83 if (file.isDirectory()) { -84 final File[] files = file.listFiles(); -85 -86 for (File f : files) { -87 try { -88 urls.add(f.toURI().toURL()); -89 } catch (MalformedURLException ex) { -90 final String msg = String.format("Unable to load database driver '%s'; invalid path provided '%s'", -91 className, f.getAbsoluteFile()); -92 LOGGER.log(Level.FINE, msg, ex); -93 throw new DriverLoadException(msg, ex); +20 import org.slf4j.Logger; +21 import org.slf4j.LoggerFactory; +22 +23 import java.io.File; +24 import java.net.MalformedURLException; +25 import java.net.URL; +26 import java.net.URLClassLoader; +27 import java.security.AccessController; +28 import java.security.PrivilegedAction; +29 import java.sql.Driver; +30 import java.sql.DriverManager; +31 import java.sql.SQLException; +32 import java.util.ArrayList; +33 import java.util.List; +34 +35 /** +36 * DriverLoader is a utility class that is used to load database drivers. +37 * +38 * @author Jeremy Long +39 */ +40 public final class DriverLoader { +41 +42 /** +43 * The logger. +44 */ +45 private static final Logger LOGGER = LoggerFactory.getLogger(DriverLoader.class); +46 +47 /** +48 * Private constructor for a utility class. +49 */ +50 private DriverLoader() { +51 } +52 +53 /** +54 * Loads the specified class using the system class loader and registers the driver with the driver manager. +55 * +56 * @param className the fully qualified name of the desired class +57 * @return the loaded Driver +58 * @throws DriverLoadException thrown if the driver cannot be loaded +59 */ +60 public static Driver load(String className) throws DriverLoadException { +61 final ClassLoader loader = DriverLoader.class.getClassLoader(); //ClassLoader.getSystemClassLoader(); +62 return load(className, loader); +63 } +64 +65 /** +66 * Loads the specified class by registering the supplied paths to the class loader and then registers the driver +67 * with the driver manager. The pathToDriver argument is added to the class loader so that an external driver can be +68 * loaded. Note, the pathToDriver can contain a semi-colon separated list of paths so any dependencies can be added +69 * as needed. If a path in the pathToDriver argument is a directory all files in the directory are added to the +70 * class path. +71 * +72 * @param className the fully qualified name of the desired class +73 * @param pathToDriver the path to the JAR file containing the driver; note, this can be a semi-colon separated list +74 * of paths +75 * @return the loaded Driver +76 * @throws DriverLoadException thrown if the driver cannot be loaded +77 */ +78 public static Driver load(String className, String pathToDriver) throws DriverLoadException { +79 final URLClassLoader parent = (URLClassLoader) ClassLoader.getSystemClassLoader(); +80 final List<URL> urls = new ArrayList<URL>(); +81 final String[] paths = pathToDriver.split(File.pathSeparator); +82 for (String path : paths) { +83 final File file = new File(path); +84 if (file.isDirectory()) { +85 final File[] files = file.listFiles(); +86 +87 for (File f : files) { +88 try { +89 urls.add(f.toURI().toURL()); +90 } catch (MalformedURLException ex) { +91 LOGGER.debug("Unable to load database driver '{}'; invalid path provided '{}'", +92 className, f.getAbsoluteFile(), ex); +93 throw new DriverLoadException("Unable to load database driver. Invalid path provided", ex); 94 } 95 } 96 } else if (file.exists()) { 97 try { 98 urls.add(file.toURI().toURL()); 99 } catch (MalformedURLException ex) { -100 final String msg = String.format("Unable to load database driver '%s'; invalid path provided '%s'", -101 className, file.getAbsoluteFile()); -102 LOGGER.log(Level.FINE, msg, ex); -103 throw new DriverLoadException(msg, ex); -104 } -105 } -106 } -107 final URLClassLoader loader = AccessController.doPrivileged(new PrivilegedAction<URLClassLoader>() { -108 @Override -109 public URLClassLoader run() { -110 return new URLClassLoader(urls.toArray(new URL[urls.size()]), parent); -111 } -112 }); -113 -114 return load(className, loader); -115 } -116 -117 /** -118 * Loads the specified class using the supplied class loader and registers the driver with the driver manager. -119 * -120 * @param className the fully qualified name of the desired class -121 * @param loader the class loader to use when loading the driver -122 * @return the loaded Driver -123 * @throws DriverLoadException thrown if the driver cannot be loaded -124 */ -125 private static Driver load(String className, ClassLoader loader) throws DriverLoadException { -126 try { -127 final Class c = Class.forName(className, true, loader); -128 //final Class c = loader.loadClass(className); -129 final Driver driver = (Driver) c.newInstance(); -130 final Driver shim = new DriverShim(driver); -131 //using the DriverShim to get around the fact that the DriverManager won't register a driver not in the base class path -132 DriverManager.registerDriver(shim); -133 return shim; -134 } catch (ClassNotFoundException ex) { -135 final String msg = String.format("Unable to load database driver '%s'", className); -136 LOGGER.log(Level.FINE, msg, ex); -137 throw new DriverLoadException(msg, ex); -138 } catch (InstantiationException ex) { -139 final String msg = String.format("Unable to load database driver '%s'", className); -140 LOGGER.log(Level.FINE, msg, ex); -141 throw new DriverLoadException(msg, ex); -142 } catch (IllegalAccessException ex) { -143 final String msg = String.format("Unable to load database driver '%s'", className); -144 LOGGER.log(Level.FINE, msg, ex); -145 throw new DriverLoadException(msg, ex); -146 } catch (SQLException ex) { -147 final String msg = String.format("Unable to load database driver '%s'", className); -148 LOGGER.log(Level.FINE, msg, ex); -149 throw new DriverLoadException(msg, ex); -150 } -151 } -152 } +100 LOGGER.debug("Unable to load database driver '{}'; invalid path provided '{}'", +101 className, file.getAbsoluteFile(), ex); +102 throw new DriverLoadException("Unable to load database driver. Invalid path provided", ex); +103 } +104 } +105 } +106 final URLClassLoader loader = AccessController.doPrivileged(new PrivilegedAction<URLClassLoader>() { +107 @Override +108 public URLClassLoader run() { +109 return new URLClassLoader(urls.toArray(new URL[urls.size()]), parent); +110 } +111 }); +112 +113 return load(className, loader); +114 } +115 +116 /** +117 * Loads the specified class using the supplied class loader and registers the driver with the driver manager. +118 * +119 * @param className the fully qualified name of the desired class +120 * @param loader the class loader to use when loading the driver +121 * @return the loaded Driver +122 * @throws DriverLoadException thrown if the driver cannot be loaded +123 */ +124 private static Driver load(String className, ClassLoader loader) throws DriverLoadException { +125 try { +126 final Class c = Class.forName(className, true, loader); +127 //final Class c = loader.loadClass(className); +128 final Driver driver = (Driver) c.newInstance(); +129 final Driver shim = new DriverShim(driver); +130 //using the DriverShim to get around the fact that the DriverManager won't register a driver not in the base class path +131 DriverManager.registerDriver(shim); +132 return shim; +133 } catch (ClassNotFoundException ex) { +134 final String msg = String.format("Unable to load database driver '%s'", className); +135 LOGGER.debug(msg, ex); +136 throw new DriverLoadException(msg, ex); +137 } catch (InstantiationException ex) { +138 final String msg = String.format("Unable to load database driver '%s'", className); +139 LOGGER.debug(msg, ex); +140 throw new DriverLoadException(msg, ex); +141 } catch (IllegalAccessException ex) { +142 final String msg = String.format("Unable to load database driver '%s'", className); +143 LOGGER.debug(msg, ex); +144 throw new DriverLoadException(msg, ex); +145 } catch (SQLException ex) { +146 final String msg = String.format("Unable to load database driver '%s'", className); +147 LOGGER.debug(msg, ex); +148 throw new DriverLoadException(msg, ex); +149 } +150 } +151 }
    diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/DriverShim.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/DriverShim.html index a0cea2257..8fd6e73bf 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/DriverShim.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/nvdcve/DriverShim.html @@ -25,191 +25,192 @@ 17 */ 18 package org.owasp.dependencycheck.data.nvdcve; 19 -20 import java.lang.reflect.InvocationTargetException; -21 import java.lang.reflect.Method; -22 import java.sql.Connection; -23 import java.sql.Driver; -24 import java.sql.DriverPropertyInfo; -25 import java.sql.SQLException; -26 import java.sql.SQLFeatureNotSupportedException; -27 import java.util.Properties; -28 import java.util.logging.Level; -29 import java.util.logging.Logger; -30 -31 /** -32 * <p> -33 * Driver shim to get around the class loader issue with the DriverManager. The following code is a nearly identical -34 * copy (with more comments and a few more methods implemented) of the DriverShim from:</p> -35 * <blockquote>http://www.kfu.com/~nsayer/Java/dyn-jdbc.html</blockquote>; -36 * -37 * @author Jeremy Long -38 * @see java.sql.Driver -39 */ -40 class DriverShim implements Driver { -41 -42 /** -43 * The logger. -44 */ -45 private static final Logger LOGGER = Logger.getLogger(DriverShim.class.getName()); -46 /** -47 * The database driver being wrapped. -48 */ -49 private final Driver driver; -50 -51 /** -52 * Constructs a new wrapper around a Driver. -53 * -54 * @param driver the database driver to wrap -55 */ -56 DriverShim(Driver driver) { -57 this.driver = driver; -58 } -59 -60 /** -61 * Wraps the underlying driver's call to acceptsURL. Returns whether or not the driver can open a connection to the -62 * given URL. -63 * -64 * @param url the URL of the database -65 * @return true if the wrapped driver can connect to the specified URL -66 * @throws SQLException thrown if there is an error connecting to the database -67 * @see java.sql.Driver#acceptsURL(java.lang.String) -68 */ -69 @Override -70 public boolean acceptsURL(String url) throws SQLException { -71 return this.driver.acceptsURL(url); -72 } -73 -74 /** -75 * Wraps the call to the underlying driver's connect method. -76 * -77 * @param url the URL of the database -78 * @param info a collection of string/value pairs -79 * @return a Connection object -80 * @throws SQLException thrown if there is an error connecting to the database -81 * @see java.sql.Driver#connect(java.lang.String, java.util.Properties) -82 */ -83 @Override -84 public Connection connect(String url, Properties info) throws SQLException { -85 return this.driver.connect(url, info); -86 } -87 -88 /** -89 * Returns the wrapped driver's major version number. -90 * -91 * @return the wrapped driver's major version number -92 * @see java.sql.Driver#getMajorVersion() -93 */ -94 @Override -95 public int getMajorVersion() { -96 return this.driver.getMajorVersion(); -97 } -98 -99 /** -100 * Returns the wrapped driver's minor version number. -101 * -102 * @return the wrapped driver's minor version number -103 * @see java.sql.Driver#getMinorVersion() -104 */ -105 @Override -106 public int getMinorVersion() { -107 return this.driver.getMinorVersion(); -108 } -109 -110 /** -111 * Wraps the call to the underlying driver's getParentLogger method. -112 * -113 * @return the parent's Logger -114 * @throws SQLFeatureNotSupportedException thrown if the feature is not supported -115 * @see java.sql.Driver#getParentLogger() -116 */ -117 //@Override -118 public Logger getParentLogger() throws SQLFeatureNotSupportedException { -119 //return driver.getParentLogger(); -120 Method m = null; -121 try { -122 m = driver.getClass().getMethod("getParentLogger"); -123 } catch (Throwable e) { -124 throw new SQLFeatureNotSupportedException(); -125 } -126 if (m != null) { -127 try { -128 return (Logger) m.invoke(m); -129 } catch (IllegalAccessException ex) { -130 LOGGER.log(Level.FINER, null, ex); -131 } catch (IllegalArgumentException ex) { -132 LOGGER.log(Level.FINER, null, ex); -133 } catch (InvocationTargetException ex) { -134 LOGGER.log(Level.FINER, null, ex); -135 } -136 } -137 throw new SQLFeatureNotSupportedException(); -138 } -139 -140 /** -141 * Wraps the call to the underlying driver's getPropertyInfo method. -142 * -143 * @param url the URL of the database -144 * @param info a collection of string/value pairs -145 * @return an array of DriverPropertyInfo objects -146 * @throws SQLException thrown if there is an error accessing the database -147 * @see java.sql.Driver#getPropertyInfo(java.lang.String, java.util.Properties) -148 */ -149 @Override -150 public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException { -151 return this.driver.getPropertyInfo(url, info); -152 } -153 -154 /** -155 * Returns whether or not the wrapped driver is jdbcCompliant. -156 * -157 * @return true if the wrapped driver is JDBC compliant; otherwise false -158 * @see java.sql.Driver#jdbcCompliant() -159 */ -160 @Override -161 public boolean jdbcCompliant() { -162 return this.driver.jdbcCompliant(); -163 } -164 -165 /** -166 * Standard implementation of hashCode. -167 * -168 * @return the hashCode of the object -169 */ -170 @Override -171 public int hashCode() { -172 int hash = 7; -173 hash = 97 * hash + (this.driver != null ? this.driver.hashCode() : 0); -174 return hash; -175 } -176 -177 /** -178 * Standard implementation of equals. -179 * -180 * @param obj the object to compare -181 * @return returns true if the objects are equal; otherwise false -182 */ -183 @Override -184 public boolean equals(Object obj) { -185 if (obj == null) { -186 return false; -187 } -188 if (getClass() != obj.getClass()) { -189 return false; -190 } -191 final DriverShim other = (DriverShim) obj; -192 return this.driver == other.driver || (this.driver != null && this.driver.equals(other.driver)); -193 } -194 -195 /** -196 * Standard implementation of toString(). -197 * -198 * @return the String representation of the object -199 */ -200 @Override -201 public String toString() { -202 return "DriverShim{" + "driver=" + driver + '}'; -203 } -204 } +20 import org.slf4j.Logger; +21 import org.slf4j.LoggerFactory; +22 +23 import java.lang.reflect.InvocationTargetException; +24 import java.lang.reflect.Method; +25 import java.sql.Connection; +26 import java.sql.Driver; +27 import java.sql.DriverPropertyInfo; +28 import java.sql.SQLException; +29 import java.sql.SQLFeatureNotSupportedException; +30 import java.util.Properties; +31 +32 /** +33 * <p> +34 * Driver shim to get around the class loader issue with the DriverManager. The following code is a nearly identical +35 * copy (with more comments and a few more methods implemented) of the DriverShim from:</p> +36 * <blockquote>http://www.kfu.com/~nsayer/Java/dyn-jdbc.html</blockquote>; +37 * +38 * @author Jeremy Long +39 * @see java.sql.Driver +40 */ +41 class DriverShim implements Driver { +42 +43 /** +44 * The logger. +45 */ +46 private static final Logger LOGGER = LoggerFactory.getLogger(DriverShim.class); +47 /** +48 * The database driver being wrapped. +49 */ +50 private final Driver driver; +51 +52 /** +53 * Constructs a new wrapper around a Driver. +54 * +55 * @param driver the database driver to wrap +56 */ +57 DriverShim(Driver driver) { +58 this.driver = driver; +59 } +60 +61 /** +62 * Wraps the underlying driver's call to acceptsURL. Returns whether or not the driver can open a connection to the +63 * given URL. +64 * +65 * @param url the URL of the database +66 * @return true if the wrapped driver can connect to the specified URL +67 * @throws SQLException thrown if there is an error connecting to the database +68 * @see java.sql.Driver#acceptsURL(java.lang.String) +69 */ +70 @Override +71 public boolean acceptsURL(String url) throws SQLException { +72 return this.driver.acceptsURL(url); +73 } +74 +75 /** +76 * Wraps the call to the underlying driver's connect method. +77 * +78 * @param url the URL of the database +79 * @param info a collection of string/value pairs +80 * @return a Connection object +81 * @throws SQLException thrown if there is an error connecting to the database +82 * @see java.sql.Driver#connect(java.lang.String, java.util.Properties) +83 */ +84 @Override +85 public Connection connect(String url, Properties info) throws SQLException { +86 return this.driver.connect(url, info); +87 } +88 +89 /** +90 * Returns the wrapped driver's major version number. +91 * +92 * @return the wrapped driver's major version number +93 * @see java.sql.Driver#getMajorVersion() +94 */ +95 @Override +96 public int getMajorVersion() { +97 return this.driver.getMajorVersion(); +98 } +99 +100 /** +101 * Returns the wrapped driver's minor version number. +102 * +103 * @return the wrapped driver's minor version number +104 * @see java.sql.Driver#getMinorVersion() +105 */ +106 @Override +107 public int getMinorVersion() { +108 return this.driver.getMinorVersion(); +109 } +110 +111 /** +112 * Wraps the call to the underlying driver's getParentLogger method. +113 * +114 * @return the parent's Logger +115 * @throws SQLFeatureNotSupportedException thrown if the feature is not supported +116 * @see java.sql.Driver#getParentLogger() +117 */ +118 //@Override +119 public java.util.logging.Logger getParentLogger() throws SQLFeatureNotSupportedException { +120 //return driver.getParentLogger(); +121 Method m = null; +122 try { +123 m = driver.getClass().getMethod("getParentLogger"); +124 } catch (Throwable e) { +125 throw new SQLFeatureNotSupportedException(); +126 } +127 if (m != null) { +128 try { +129 return (java.util.logging.Logger) m.invoke(m); +130 } catch (IllegalAccessException ex) { +131 LOGGER.trace("", ex); +132 } catch (IllegalArgumentException ex) { +133 LOGGER.trace("", ex); +134 } catch (InvocationTargetException ex) { +135 LOGGER.trace("", ex); +136 } +137 } +138 throw new SQLFeatureNotSupportedException(); +139 } +140 +141 /** +142 * Wraps the call to the underlying driver's getPropertyInfo method. +143 * +144 * @param url the URL of the database +145 * @param info a collection of string/value pairs +146 * @return an array of DriverPropertyInfo objects +147 * @throws SQLException thrown if there is an error accessing the database +148 * @see java.sql.Driver#getPropertyInfo(java.lang.String, java.util.Properties) +149 */ +150 @Override +151 public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException { +152 return this.driver.getPropertyInfo(url, info); +153 } +154 +155 /** +156 * Returns whether or not the wrapped driver is jdbcCompliant. +157 * +158 * @return true if the wrapped driver is JDBC compliant; otherwise false +159 * @see java.sql.Driver#jdbcCompliant() +160 */ +161 @Override +162 public boolean jdbcCompliant() { +163 return this.driver.jdbcCompliant(); +164 } +165 +166 /** +167 * Standard implementation of hashCode. +168 * +169 * @return the hashCode of the object +170 */ +171 @Override +172 public int hashCode() { +173 int hash = 7; +174 hash = 97 * hash + (this.driver != null ? this.driver.hashCode() : 0); +175 return hash; +176 } +177 +178 /** +179 * Standard implementation of equals. +180 * +181 * @param obj the object to compare +182 * @return returns true if the objects are equal; otherwise false +183 */ +184 @Override +185 public boolean equals(Object obj) { +186 if (obj == null) { +187 return false; +188 } +189 if (getClass() != obj.getClass()) { +190 return false; +191 } +192 final DriverShim other = (DriverShim) obj; +193 return this.driver == other.driver || (this.driver != null && this.driver.equals(other.driver)); +194 } +195 +196 /** +197 * Standard implementation of toString(). +198 * +199 * @return the String representation of the object +200 */ +201 @Override +202 public String toString() { +203 return "DriverShim{" + "driver=" + driver + '}'; +204 } +205 }
    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 97402dd28..19538a88d 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.2.11 Reference Package org.owasp.dependencycheck.data.nvdcve + Dependency-Check Core 1.3.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 5761f7158..f0d2d34a5 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.2.11 Reference Package org.owasp.dependencycheck.data.nvdcve + Dependency-Check Core 1.3.0 Reference Package org.owasp.dependencycheck.data.nvdcve diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/BaseUpdater.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/BaseUpdater.html new file mode 100644 index 000000000..74315b21e --- /dev/null +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/BaseUpdater.html @@ -0,0 +1,101 @@ + + + +BaseUpdater 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) 2015 Jeremy Long. All Rights Reserved.
    +17   */
    +18  package org.owasp.dependencycheck.data.update;
    +19  
    +20  import org.owasp.dependencycheck.data.nvdcve.CveDB;
    +21  import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
    +22  import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties;
    +23  import org.owasp.dependencycheck.data.update.exception.UpdateException;
    +24  import org.slf4j.Logger;
    +25  import org.slf4j.LoggerFactory;
    +26  
    +27  /**
    +28   *
    +29   * @author Jeremy Long
    +30   */
    +31  public abstract class BaseUpdater {
    +32  
    +33      /**
    +34       * Static logger.
    +35       */
    +36      private static final Logger LOGGER = LoggerFactory.getLogger(BaseUpdater.class);
    +37      /**
    +38       * Information about the timestamps and URLs for data that needs to be updated.
    +39       */
    +40      private DatabaseProperties properties;
    +41      /**
    +42       * Reference to the Cve Database.
    +43       */
    +44      private CveDB cveDB = null;
    +45  
    +46      protected CveDB getCveDB() {
    +47          return cveDB;
    +48      }
    +49  
    +50      protected DatabaseProperties getProperties() {
    +51          return properties;
    +52      }
    +53  
    +54      /**
    +55       * Closes the CVE and CPE data stores.
    +56       */
    +57      protected void closeDataStores() {
    +58          if (cveDB != null) {
    +59              try {
    +60                  cveDB.close();
    +61                  cveDB = null;
    +62                  properties = null;
    +63              } catch (Throwable ignore) {
    +64                  LOGGER.trace("Error closing the database", ignore);
    +65              }
    +66          }
    +67      }
    +68  
    +69      /**
    +70       * Opens the data store.
    +71       *
    +72       * @throws UpdateException thrown if a data store cannot be opened
    +73       */
    +74      protected final void openDataStores() throws UpdateException {
    +75          if (cveDB != null) {
    +76              return;
    +77          }
    +78          try {
    +79              cveDB = new CveDB();
    +80              cveDB.open();
    +81              properties = cveDB.getDatabaseProperties();
    +82          } catch (DatabaseException ex) {
    +83              closeDataStores();
    +84              LOGGER.debug("Database Exception opening databases", ex);
    +85              throw new UpdateException("Error updating the database, please see the log file for more details.");
    +86          }
    +87      }
    +88  }
    +
    +
    + + + diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/CpeUpdater.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/CpeUpdater.html new file mode 100644 index 000000000..521af1546 --- /dev/null +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/CpeUpdater.html @@ -0,0 +1,211 @@ + + + +CpeUpdater 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) 2015 Jeremy Long. All Rights Reserved.
    +17   */
    +18  package org.owasp.dependencycheck.data.update;
    +19  
    +20  import java.io.File;
    +21  import java.io.FileInputStream;
    +22  import java.io.FileNotFoundException;
    +23  import java.io.FileOutputStream;
    +24  import java.io.IOException;
    +25  import java.net.MalformedURLException;
    +26  import java.net.URL;
    +27  import java.util.Date;
    +28  import java.util.List;
    +29  import java.util.zip.GZIPInputStream;
    +30  import javax.xml.parsers.ParserConfigurationException;
    +31  import javax.xml.parsers.SAXParser;
    +32  import javax.xml.parsers.SAXParserFactory;
    +33  import org.apache.commons.io.FileUtils;
    +34  import static org.owasp.dependencycheck.data.nvdcve.DatabaseProperties.LAST_CPE_UPDATE;
    +35  import org.owasp.dependencycheck.data.update.cpe.CPEHandler;
    +36  import org.owasp.dependencycheck.data.update.cpe.Cpe;
    +37  import org.owasp.dependencycheck.data.update.exception.UpdateException;
    +38  import org.owasp.dependencycheck.utils.DateUtil;
    +39  import org.owasp.dependencycheck.utils.DownloadFailedException;
    +40  import org.owasp.dependencycheck.utils.Downloader;
    +41  import org.owasp.dependencycheck.utils.Settings;
    +42  import org.slf4j.Logger;
    +43  import org.slf4j.LoggerFactory;
    +44  import org.xml.sax.SAXException;
    +45  
    +46  /**
    +47   * The CpeUpdater is designed to download the CPE data file from NIST and import the data into the database. However, as this
    +48   * currently adds no beneficial data, compared to what is in the CPE data contained in the CVE data files, this class is not
    +49   * currently used. The code is being kept as a future update may utilize more data from the CPE xml files.
    +50   *
    +51   * @author Jeremy Long
    +52   */
    +53  public class CpeUpdater extends BaseUpdater implements CachedWebDataSource {
    +54  
    +55      /**
    +56       * Static logger.
    +57       */
    +58      private static final Logger LOGGER = LoggerFactory.getLogger(CpeUpdater.class);
    +59  
    +60      @Override
    +61      public void update() throws UpdateException {
    +62          try {
    +63              openDataStores();
    +64              if (updateNeeded()) {
    +65                  LOGGER.info("Updating the Common Platform Enumeration (CPE)");
    +66                  final File xml = downloadCpe();
    +67                  final List<Cpe> cpes = processXML(xml);
    +68                  getCveDB().deleteUnusedCpe();
    +69                  for (Cpe cpe : cpes) {
    +70                      getCveDB().addCpe(cpe.getValue(), cpe.getVendor(), cpe.getProduct());
    +71                  }
    +72                  final Date now = new Date();
    +73                  getProperties().save(LAST_CPE_UPDATE, Long.toString(now.getTime()));
    +74                  LOGGER.info("CPE update complete");
    +75              }
    +76          } finally {
    +77              closeDataStores();
    +78          }
    +79      }
    +80  
    +81      /**
    +82       * Downloads the CPE XML file.
    +83       *
    +84       * @return the file reference to the CPE.xml file
    +85       * @throws UpdateException thrown if there is an issue downloading the XML file
    +86       */
    +87      private File downloadCpe() throws UpdateException {
    +88          File xml;
    +89          final URL url;
    +90          try {
    +91              url = new URL(Settings.getString(Settings.KEYS.CPE_URL));
    +92              xml = File.createTempFile("cpe", ".xml", Settings.getTempDirectory());
    +93              Downloader.fetchFile(url, xml);
    +94              if (url.toExternalForm().endsWith(".xml.gz")) {
    +95                  extractGzip(xml);
    +96              }
    +97  
    +98          } catch (MalformedURLException ex) {
    +99              throw new UpdateException("Invalid CPE URL", ex);
    +100         } catch (DownloadFailedException ex) {
    +101             throw new UpdateException("Unable to download CPE XML file", ex);
    +102         } catch (IOException ex) {
    +103             throw new UpdateException("Unable to create temporary file to download CPE", ex);
    +104         }
    +105         return xml;
    +106     }
    +107 
    +108     /**
    +109      * Parses the CPE XML file to return a list of CPE entries.
    +110      *
    +111      * @param xml the CPE data file
    +112      * @return the list of CPE entries
    +113      * @throws UpdateException thrown if there is an issue with parsing the XML file
    +114      */
    +115     private List<Cpe> processXML(final File xml) throws UpdateException {
    +116         try {
    +117             final SAXParserFactory factory = SAXParserFactory.newInstance();
    +118             final SAXParser saxParser = factory.newSAXParser();
    +119             final CPEHandler handler = new CPEHandler();
    +120             saxParser.parse(xml, handler);
    +121             return handler.getData();
    +122         } catch (ParserConfigurationException ex) {
    +123             throw new UpdateException("Unable to parse CPE XML file due to SAX Parser Issue", ex);
    +124         } catch (SAXException ex) {
    +125             throw new UpdateException("Unable to parse CPE XML file due to SAX Parser Exception", ex);
    +126         } catch (IOException ex) {
    +127             throw new UpdateException("Unable to parse CPE XML file due to IO Failure", ex);
    +128         }
    +129     }
    +130 
    +131     /**
    +132      * Checks to find the last time the CPE data was refreshed and if it needs to be updated.
    +133      *
    +134      * @return true if the CPE data should be refreshed
    +135      */
    +136     private boolean updateNeeded() {
    +137         final Date now = new Date();
    +138         final int days = Settings.getInt(Settings.KEYS.CVE_MODIFIED_VALID_FOR_DAYS, 30);
    +139         long timestamp = 0;
    +140         final String ts = getProperties().getProperty(LAST_CPE_UPDATE);
    +141         if (ts != null && ts.matches("^[0-9]+$")) {
    +142             timestamp = Long.parseLong(ts);
    +143         }
    +144         return !DateUtil.withinDateRange(timestamp, now.getTime(), days);
    +145     }
    +146 
    +147     /**
    +148      * Extracts the file contained in a gzip archive. The extracted file is placed in the exact same path as the file specified.
    +149      *
    +150      * @param file the archive file
    +151      * @throws FileNotFoundException thrown if the file does not exist
    +152      * @throws IOException thrown if there is an error extracting the file.
    +153      */
    +154     private void extractGzip(File file) throws FileNotFoundException, IOException {
    +155         //TODO - move this to a util class as it is duplicative of (copy of) code in the DownloadTask
    +156         final String originalPath = file.getPath();
    +157         final File gzip = new File(originalPath + ".gz");
    +158         if (gzip.isFile() && !gzip.delete()) {
    +159             gzip.deleteOnExit();
    +160         }
    +161         if (!file.renameTo(gzip)) {
    +162             throw new IOException("Unable to rename '" + file.getPath() + "'");
    +163         }
    +164         final File newfile = new File(originalPath);
    +165 
    +166         final byte[] buffer = new byte[4096];
    +167 
    +168         GZIPInputStream cin = null;
    +169         FileOutputStream out = null;
    +170         try {
    +171             cin = new GZIPInputStream(new FileInputStream(gzip));
    +172             out = new FileOutputStream(newfile);
    +173 
    +174             int len;
    +175             while ((len = cin.read(buffer)) > 0) {
    +176                 out.write(buffer, 0, len);
    +177             }
    +178         } finally {
    +179             if (cin != null) {
    +180                 try {
    +181                     cin.close();
    +182                 } catch (IOException ex) {
    +183                     LOGGER.trace("ignore", ex);
    +184                 }
    +185             }
    +186             if (out != null) {
    +187                 try {
    +188                     out.close();
    +189                 } catch (IOException ex) {
    +190                     LOGGER.trace("ignore", ex);
    +191                 }
    +192             }
    +193             if (gzip.isFile()) {
    +194                 FileUtils.deleteQuietly(gzip);
    +195             }
    +196         }
    +197     }
    +198 }
    +
    +
    + + + diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/EngineVersionCheck.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/EngineVersionCheck.html index 77a06d8fb..62e6a27b1 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/EngineVersionCheck.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/EngineVersionCheck.html @@ -30,18 +30,18 @@ 22 import java.net.MalformedURLException; 23 import java.net.URL; 24 import java.util.Date; -25 import java.util.logging.Level; -26 import java.util.logging.Logger; -27 import org.apache.commons.io.IOUtils; -28 import org.owasp.dependencycheck.data.nvdcve.CveDB; -29 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; -30 import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties; -31 import org.owasp.dependencycheck.data.update.exception.UpdateException; -32 import org.owasp.dependencycheck.utils.DateUtil; -33 import org.owasp.dependencycheck.utils.DependencyVersion; -34 import org.owasp.dependencycheck.utils.Settings; -35 import org.owasp.dependencycheck.utils.URLConnectionFactory; -36 import org.owasp.dependencycheck.utils.URLConnectionFailureException; +25 import org.apache.commons.io.IOUtils; +26 import org.owasp.dependencycheck.data.nvdcve.CveDB; +27 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; +28 import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties; +29 import org.owasp.dependencycheck.data.update.exception.UpdateException; +30 import org.owasp.dependencycheck.utils.DateUtil; +31 import org.owasp.dependencycheck.utils.DependencyVersion; +32 import org.owasp.dependencycheck.utils.Settings; +33 import org.owasp.dependencycheck.utils.URLConnectionFactory; +34 import org.owasp.dependencycheck.utils.URLConnectionFailureException; +35 import org.slf4j.Logger; +36 import org.slf4j.LoggerFactory; 37 38 /** 39 * @@ -52,7 +52,7 @@ 44 /** 45 * Static logger. 46 */ -47 private static final Logger LOGGER = Logger.getLogger(EngineVersionCheck.class.getName()); +47 private static final Logger LOGGER = LoggerFactory.getLogger(EngineVersionCheck.class); 48 /** 49 * The property key indicating when the last version check occurred. 50 */ @@ -93,96 +93,96 @@ 85 public void update() throws UpdateException { 86 try { 87 openDatabase(); -88 LOGGER.fine("Begin Engine Version Check"); +88 LOGGER.debug("Begin Engine Version Check"); 89 final DatabaseProperties properties = cveDB.getDatabaseProperties(); 90 final long lastChecked = Long.parseLong(properties.getProperty(ENGINE_VERSION_CHECKED_ON, "0")); 91 final long now = (new Date()).getTime(); 92 updateToVersion = properties.getProperty(CURRENT_ENGINE_RELEASE, ""); 93 final String currentVersion = Settings.getString(Settings.KEYS.APPLICATION_VERSION, "0.0.0"); -94 LOGGER.fine("Last checked: " + lastChecked); -95 LOGGER.fine("Now: " + now); -96 LOGGER.fine("Current version: " + currentVersion); +94 LOGGER.debug("Last checked: {}", lastChecked); +95 LOGGER.debug("Now: {}", now); +96 LOGGER.debug("Current version: {}", currentVersion); 97 final boolean updateNeeded = shouldUpdate(lastChecked, now, properties, currentVersion); 98 if (updateNeeded) { -99 final String msg = String.format("A new version of dependency-check is available. Consider updating to version %s.", +99 LOGGER.warn("A new version of dependency-check is available. Consider updating to version {}.", 100 updateToVersion); -101 LOGGER.warning(msg); -102 } -103 } catch (DatabaseException ex) { -104 LOGGER.log(Level.FINE, "Database Exception opening databases to retrieve properties", ex); -105 throw new UpdateException("Error occured updating database properties."); -106 } finally { -107 closeDatabase(); -108 } -109 } -110 -111 /** -112 * Determines if a new version of the dependency-check engine has been released. -113 * -114 * @param lastChecked the epoch time of the last version check -115 * @param now the current epoch time -116 * @param properties the database properties object -117 * @param currentVersion the current version of dependency-check -118 * @return <code>true</code> if a newer version of the database has been released; otherwise <code>false</code> -119 * @throws UpdateException thrown if there is an error connecting to the github documentation site or accessing the -120 * local database. -121 */ -122 protected boolean shouldUpdate(final long lastChecked, final long now, final DatabaseProperties properties, -123 String currentVersion) throws UpdateException { -124 //check every 30 days if we know there is an update, otherwise check every 7 days -125 int checkRange = 30; -126 if (updateToVersion.isEmpty()) { -127 checkRange = 7; -128 } -129 if (!DateUtil.withinDateRange(lastChecked, now, checkRange)) { -130 LOGGER.fine("Checking web for new version."); -131 final String currentRelease = getCurrentReleaseVersion(); -132 if (currentRelease != null) { -133 final DependencyVersion v = new DependencyVersion(currentRelease); -134 if (v.getVersionParts() != null && v.getVersionParts().size() >= 3) { -135 updateToVersion = v.toString(); -136 if (!currentRelease.equals(updateToVersion)) { -137 properties.save(CURRENT_ENGINE_RELEASE, updateToVersion); -138 } else { -139 properties.save(CURRENT_ENGINE_RELEASE, ""); -140 } -141 properties.save(ENGINE_VERSION_CHECKED_ON, Long.toString(now)); -142 } -143 } -144 LOGGER.log(Level.FINE, "Current Release: {0}", updateToVersion); -145 } -146 final DependencyVersion running = new DependencyVersion(currentVersion); -147 final DependencyVersion released = new DependencyVersion(updateToVersion); -148 if (running.compareTo(released) < 0) { -149 LOGGER.fine("Upgrade recommended"); -150 return true; -151 } -152 LOGGER.fine("Upgrade not needed"); -153 return false; -154 } -155 -156 /** -157 * Opens the CVE and CPE data stores. -158 * -159 * @throws DatabaseException thrown if a data store cannot be opened -160 */ -161 protected final void openDatabase() throws DatabaseException { -162 if (cveDB != null) { -163 return; -164 } -165 cveDB = new CveDB(); -166 cveDB.open(); -167 } -168 -169 /** -170 * Closes the CVE and CPE data stores. -171 */ -172 protected void closeDatabase() { -173 if (cveDB != null) { -174 try { -175 cveDB.close(); +101 } +102 } catch (DatabaseException ex) { +103 LOGGER.debug("Database Exception opening databases to retrieve properties", ex); +104 throw new UpdateException("Error occured updating database properties."); +105 } finally { +106 closeDatabase(); +107 } +108 } +109 +110 /** +111 * Determines if a new version of the dependency-check engine has been released. +112 * +113 * @param lastChecked the epoch time of the last version check +114 * @param now the current epoch time +115 * @param properties the database properties object +116 * @param currentVersion the current version of dependency-check +117 * @return <code>true</code> if a newer version of the database has been released; otherwise <code>false</code> +118 * @throws UpdateException thrown if there is an error connecting to the github documentation site or accessing the local +119 * database. +120 */ +121 protected boolean shouldUpdate(final long lastChecked, final long now, final DatabaseProperties properties, +122 String currentVersion) throws UpdateException { +123 //check every 30 days if we know there is an update, otherwise check every 7 days +124 int checkRange = 30; +125 if (updateToVersion.isEmpty()) { +126 checkRange = 7; +127 } +128 if (!DateUtil.withinDateRange(lastChecked, now, checkRange)) { +129 LOGGER.debug("Checking web for new version."); +130 final String currentRelease = getCurrentReleaseVersion(); +131 if (currentRelease != null) { +132 final DependencyVersion v = new DependencyVersion(currentRelease); +133 if (v.getVersionParts() != null && v.getVersionParts().size() >= 3) { +134 updateToVersion = v.toString(); +135 if (!currentRelease.equals(updateToVersion)) { +136 properties.save(CURRENT_ENGINE_RELEASE, updateToVersion); +137 } else { +138 properties.save(CURRENT_ENGINE_RELEASE, ""); +139 } +140 properties.save(ENGINE_VERSION_CHECKED_ON, Long.toString(now)); +141 } +142 } +143 LOGGER.debug("Current Release: {}", updateToVersion); +144 } +145 final DependencyVersion running = new DependencyVersion(currentVersion); +146 final DependencyVersion released = new DependencyVersion(updateToVersion); +147 if (running.compareTo(released) < 0) { +148 LOGGER.debug("Upgrade recommended"); +149 return true; +150 } +151 LOGGER.debug("Upgrade not needed"); +152 return false; +153 } +154 +155 /** +156 * Opens the CVE and CPE data stores. +157 * +158 * @throws DatabaseException thrown if a data store cannot be opened +159 */ +160 protected final void openDatabase() throws DatabaseException { +161 if (cveDB != null) { +162 return; +163 } +164 cveDB = new CveDB(); +165 cveDB.open(); +166 } +167 +168 /** +169 * Closes the CVE and CPE data stores. +170 */ +171 protected void closeDatabase() { +172 if (cveDB != null) { +173 try { +174 cveDB.close(); +175 cveDB = null; 176 } catch (Throwable ignore) { -177 LOGGER.log(Level.FINEST, "Error closing the cveDB", ignore); +177 LOGGER.trace("Error closing the cveDB", ignore); 178 } 179 } 180 } @@ -207,11 +207,11 @@ 199 return releaseVersion.trim(); 200 } 201 } catch (MalformedURLException ex) { -202 LOGGER.log(Level.FINE, "unable to retrieve current release version of dependency-check", ex); +202 LOGGER.debug("unable to retrieve current release version of dependency-check", ex); 203 } catch (URLConnectionFailureException ex) { -204 LOGGER.log(Level.FINE, "unable to retrieve current release version of dependency-check", ex); +204 LOGGER.debug("unable to retrieve current release version of dependency-check", ex); 205 } catch (IOException ex) { -206 LOGGER.log(Level.FINE, "unable to retrieve current release version of dependency-check", ex); +206 LOGGER.debug("unable to retrieve current release version of dependency-check", ex); 207 } finally { 208 if (conn != null) { 209 conn.disconnect(); 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 deaee7b35..317db3ddd 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 @@ -26,52 +26,271 @@ 18 package org.owasp.dependencycheck.data.update; 19 20 import java.net.MalformedURLException; -21 import java.util.logging.Level; -22 import java.util.logging.Logger; -23 import org.owasp.dependencycheck.data.update.exception.UpdateException; -24 import org.owasp.dependencycheck.utils.DownloadFailedException; -25 import org.owasp.dependencycheck.utils.Settings; -26 -27 /** -28 * Class responsible for updating the NVD CVE and CPE data stores. -29 * -30 * @author Jeremy Long -31 */ -32 public class NvdCveUpdater implements CachedWebDataSource { -33 -34 /** -35 * The logger -36 */ -37 private static final Logger LOGGER = Logger.getLogger(NvdCveUpdater.class.getName()); -38 -39 /** -40 * <p> -41 * Downloads the latest NVD CVE XML file from the web and imports it into the current CVE Database.</p> -42 * -43 * @throws UpdateException is thrown if there is an error updating the database -44 */ -45 @Override -46 public void update() throws UpdateException { -47 try { -48 final StandardUpdate task = new StandardUpdate(); -49 if (task.isUpdateNeeded()) { -50 task.update(); -51 } -52 } catch (MalformedURLException ex) { -53 LOGGER.log(Level.WARNING, -54 "NVD CVE properties files contain an invalid URL, unable to update the data to use the most current data."); -55 LOGGER.log(Level.FINE, null, ex); -56 } catch (DownloadFailedException ex) { -57 LOGGER.log(Level.WARNING, -58 "Unable to download the NVD CVE data; the results may not include the most recent CPE/CVEs from the NVD."); -59 if (Settings.getString(Settings.KEYS.PROXY_SERVER) == null) { -60 LOGGER.log(Level.INFO, -61 "If you are behind a proxy you may need to configure dependency-check to use the proxy."); -62 } -63 LOGGER.log(Level.FINE, null, ex); -64 } -65 } -66 } +21 import java.util.Calendar; +22 import java.util.Date; +23 import java.util.HashSet; +24 import java.util.Set; +25 import java.util.concurrent.ExecutionException; +26 import java.util.concurrent.ExecutorService; +27 import java.util.concurrent.Executors; +28 import java.util.concurrent.Future; +29 import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties; +30 import static org.owasp.dependencycheck.data.nvdcve.DatabaseProperties.MODIFIED; +31 import org.owasp.dependencycheck.data.update.exception.InvalidDataException; +32 import org.owasp.dependencycheck.data.update.exception.UpdateException; +33 import org.owasp.dependencycheck.data.update.nvd.DownloadTask; +34 import org.owasp.dependencycheck.data.update.nvd.NvdCveInfo; +35 import org.owasp.dependencycheck.data.update.nvd.ProcessTask; +36 import org.owasp.dependencycheck.data.update.nvd.UpdateableNvdCve; +37 import org.owasp.dependencycheck.utils.DateUtil; +38 import org.owasp.dependencycheck.utils.DownloadFailedException; +39 import org.owasp.dependencycheck.utils.InvalidSettingException; +40 import org.owasp.dependencycheck.utils.Settings; +41 import org.slf4j.Logger; +42 import org.slf4j.LoggerFactory; +43 +44 /** +45 * Class responsible for updating the NVD CVE data. +46 * +47 * @author Jeremy Long +48 */ +49 public class NvdCveUpdater extends BaseUpdater implements CachedWebDataSource { +50 +51 /** +52 * The logger +53 */ +54 private static final Logger LOGGER = LoggerFactory.getLogger(NvdCveUpdater.class); +55 /** +56 * The max thread pool size to use when downloading files. +57 */ +58 public static final int MAX_THREAD_POOL_SIZE = Settings.getInt(Settings.KEYS.MAX_DOWNLOAD_THREAD_POOL_SIZE, 3); +59 +60 /** +61 * <p> +62 * Downloads the latest NVD CVE XML file from the web and imports it into the current CVE Database.</p> +63 * +64 * @throws UpdateException is thrown if there is an error updating the database +65 */ +66 @Override +67 public void update() throws UpdateException { +68 try { +69 openDataStores(); +70 final UpdateableNvdCve updateable = getUpdatesNeeded(); +71 if (updateable.isUpdateNeeded()) { +72 performUpdate(updateable); +73 } +74 } catch (MalformedURLException ex) { +75 LOGGER.warn( +76 "NVD CVE properties files contain an invalid URL, unable to update the data to use the most current data."); +77 LOGGER.debug("", ex); +78 } catch (DownloadFailedException ex) { +79 LOGGER.warn( +80 "Unable to download the NVD CVE data; the results may not include the most recent CPE/CVEs from the NVD."); +81 if (Settings.getString(Settings.KEYS.PROXY_SERVER) == null) { +82 LOGGER.info( +83 "If you are behind a proxy you may need to configure dependency-check to use the proxy."); +84 } +85 LOGGER.debug("", ex); +86 } finally { +87 closeDataStores(); +88 } +89 } +90 +91 /** +92 * Downloads the latest NVD CVE XML file from the web and imports it into the current CVE Database. +93 * +94 * @param updateable a collection of NVD CVE data file references that need to be downloaded and processed to update the +95 * database +96 * @throws UpdateException is thrown if there is an error updating the database +97 */ +98 public void performUpdate(UpdateableNvdCve updateable) throws UpdateException { +99 int maxUpdates = 0; +100 try { +101 for (NvdCveInfo cve : updateable) { +102 if (cve.getNeedsUpdate()) { +103 maxUpdates += 1; +104 } +105 } +106 if (maxUpdates <= 0) { +107 return; +108 } +109 if (maxUpdates > 3) { +110 LOGGER.info( +111 "NVD CVE requires several updates; this could take a couple of minutes."); +112 } +113 if (maxUpdates > 0) { +114 openDataStores(); +115 } +116 +117 final int poolSize = (MAX_THREAD_POOL_SIZE < maxUpdates) ? MAX_THREAD_POOL_SIZE : maxUpdates; +118 +119 final ExecutorService downloadExecutors = Executors.newFixedThreadPool(poolSize); +120 final ExecutorService processExecutor = Executors.newSingleThreadExecutor(); +121 final Set<Future<Future<ProcessTask>>> downloadFutures = new HashSet<Future<Future<ProcessTask>>>(maxUpdates); +122 for (NvdCveInfo cve : updateable) { +123 if (cve.getNeedsUpdate()) { +124 final DownloadTask call = new DownloadTask(cve, processExecutor, getCveDB(), Settings.getInstance()); +125 downloadFutures.add(downloadExecutors.submit(call)); +126 } +127 } +128 downloadExecutors.shutdown(); +129 +130 //next, move the future future processTasks to just future processTasks +131 final Set<Future<ProcessTask>> processFutures = new HashSet<Future<ProcessTask>>(maxUpdates); +132 for (Future<Future<ProcessTask>> future : downloadFutures) { +133 Future<ProcessTask> task = null; +134 try { +135 task = future.get(); +136 } catch (InterruptedException ex) { +137 downloadExecutors.shutdownNow(); +138 processExecutor.shutdownNow(); +139 +140 LOGGER.debug("Thread was interrupted during download", ex); +141 throw new UpdateException("The download was interrupted", ex); +142 } catch (ExecutionException ex) { +143 downloadExecutors.shutdownNow(); +144 processExecutor.shutdownNow(); +145 +146 LOGGER.debug("Thread was interrupted during download execution", ex); +147 throw new UpdateException("The execution of the download was interrupted", ex); +148 } +149 if (task == null) { +150 downloadExecutors.shutdownNow(); +151 processExecutor.shutdownNow(); +152 LOGGER.debug("Thread was interrupted during download"); +153 throw new UpdateException("The download was interrupted; unable to complete the update"); +154 } else { +155 processFutures.add(task); +156 } +157 } +158 +159 for (Future<ProcessTask> future : processFutures) { +160 try { +161 final ProcessTask task = future.get(); +162 if (task.getException() != null) { +163 throw task.getException(); +164 } +165 } catch (InterruptedException ex) { +166 processExecutor.shutdownNow(); +167 LOGGER.debug("Thread was interrupted during processing", ex); +168 throw new UpdateException(ex); +169 } catch (ExecutionException ex) { +170 processExecutor.shutdownNow(); +171 LOGGER.debug("Execution Exception during process", ex); +172 throw new UpdateException(ex); +173 } finally { +174 processExecutor.shutdown(); +175 } +176 } +177 +178 if (maxUpdates >= 1) { //ensure the modified file date gets written (we may not have actually updated it) +179 getProperties().save(updateable.get(MODIFIED)); +180 LOGGER.info("Begin database maintenance."); +181 getCveDB().cleanupDatabase(); +182 LOGGER.info("End database maintenance."); +183 } +184 } finally { +185 closeDataStores(); +186 } +187 } +188 +189 /** +190 * Determines if the index needs to be updated. This is done by fetching the NVD CVE meta data and checking the last update +191 * date. If the data needs to be refreshed this method will return the NvdCveUrl for the files that need to be updated. +192 * +193 * @return the collection of files that need to be updated +194 * @throws MalformedURLException is thrown if the URL for the NVD CVE Meta data is incorrect +195 * @throws DownloadFailedException is thrown if there is an error. downloading the NVD CVE download data file +196 * @throws UpdateException Is thrown if there is an issue with the last updated properties file +197 */ +198 protected final UpdateableNvdCve getUpdatesNeeded() throws MalformedURLException, DownloadFailedException, UpdateException { +199 UpdateableNvdCve updates = null; +200 try { +201 updates = retrieveCurrentTimestampsFromWeb(); +202 } catch (InvalidDataException ex) { +203 final String msg = "Unable to retrieve valid timestamp from nvd cve downloads page"; +204 LOGGER.debug(msg, ex); +205 throw new DownloadFailedException(msg, ex); +206 } catch (InvalidSettingException ex) { +207 LOGGER.debug("Invalid setting found when retrieving timestamps", ex); +208 throw new DownloadFailedException("Invalid settings", ex); +209 } +210 +211 if (updates == null) { +212 throw new DownloadFailedException("Unable to retrieve the timestamps of the currently published NVD CVE data"); +213 } +214 if (!getProperties().isEmpty()) { +215 try { +216 final long lastUpdated = Long.parseLong(getProperties().getProperty(DatabaseProperties.LAST_UPDATED, "0")); +217 final Date now = new Date(); +218 final int days = Settings.getInt(Settings.KEYS.CVE_MODIFIED_VALID_FOR_DAYS, 7); +219 if (lastUpdated == updates.getTimeStamp(MODIFIED)) { +220 updates.clear(); //we don't need to update anything. +221 } else if (DateUtil.withinDateRange(lastUpdated, now.getTime(), days)) { +222 for (NvdCveInfo entry : updates) { +223 if (MODIFIED.equals(entry.getId())) { +224 entry.setNeedsUpdate(true); +225 } else { +226 entry.setNeedsUpdate(false); +227 } +228 } +229 } else { //we figure out which of the several XML files need to be downloaded. +230 for (NvdCveInfo entry : updates) { +231 if (MODIFIED.equals(entry.getId())) { +232 entry.setNeedsUpdate(true); +233 } else { +234 long currentTimestamp = 0; +235 try { +236 currentTimestamp = Long.parseLong(getProperties().getProperty(DatabaseProperties.LAST_UPDATED_BASE +237 + entry.getId(), "0")); +238 } catch (NumberFormatException ex) { +239 LOGGER.debug("Error parsing '{}' '{}' from nvdcve.lastupdated", +240 DatabaseProperties.LAST_UPDATED_BASE, entry.getId(), ex); +241 } +242 if (currentTimestamp == entry.getTimestamp()) { +243 entry.setNeedsUpdate(false); +244 } +245 } +246 } +247 } +248 } catch (NumberFormatException ex) { +249 LOGGER.warn("An invalid schema version or timestamp exists in the data.properties file."); +250 LOGGER.debug("", ex); +251 } +252 } +253 return updates; +254 } +255 +256 /** +257 * Retrieves the timestamps from the NVD CVE meta data file. +258 * +259 * @return the timestamp from the currently published nvdcve downloads page +260 * @throws MalformedURLException thrown if the URL for the NVD CCE Meta data is incorrect. +261 * @throws DownloadFailedException thrown if there is an error downloading the nvd cve meta data file +262 * @throws InvalidDataException thrown if there is an exception parsing the timestamps +263 * @throws InvalidSettingException thrown if the settings are invalid +264 */ +265 private UpdateableNvdCve retrieveCurrentTimestampsFromWeb() +266 throws MalformedURLException, DownloadFailedException, InvalidDataException, InvalidSettingException { +267 +268 final UpdateableNvdCve updates = new UpdateableNvdCve(); +269 updates.add(MODIFIED, Settings.getString(Settings.KEYS.CVE_MODIFIED_20_URL), +270 Settings.getString(Settings.KEYS.CVE_MODIFIED_12_URL), +271 false); +272 +273 final int start = Settings.getInt(Settings.KEYS.CVE_START_YEAR); +274 final int end = Calendar.getInstance().get(Calendar.YEAR); +275 final String baseUrl20 = Settings.getString(Settings.KEYS.CVE_SCHEMA_2_0); +276 final String baseUrl12 = Settings.getString(Settings.KEYS.CVE_SCHEMA_1_2); +277 for (int i = start; i <= end; i++) { +278 updates.add(Integer.toString(i), String.format(baseUrl20, i), +279 String.format(baseUrl12, i), +280 true); +281 } +282 return updates; +283 } +284 +285 }
    diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/cpe/CPEHandler.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/cpe/CPEHandler.html new file mode 100644 index 000000000..8707a6919 --- /dev/null +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/cpe/CPEHandler.html @@ -0,0 +1,377 @@ + + + +CPEHandler 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) 2015 Jeremy Long. All Rights Reserved.
    +17   */
    +18  package org.owasp.dependencycheck.data.update.cpe;
    +19  
    +20  import java.io.UnsupportedEncodingException;
    +21  import java.util.ArrayList;
    +22  import java.util.List;
    +23  import org.owasp.dependencycheck.data.update.NvdCveUpdater;
    +24  import org.owasp.dependencycheck.data.update.exception.InvalidDataException;
    +25  import org.slf4j.Logger;
    +26  import org.slf4j.LoggerFactory;
    +27  import org.xml.sax.Attributes;
    +28  import org.xml.sax.SAXException;
    +29  import org.xml.sax.helpers.DefaultHandler;
    +30  
    +31  /**
    +32   * A SAX Handler that will parse the CPE XML and load it into the databse.
    +33   *
    +34   * @author Jeremy Long
    +35   */
    +36  public class CPEHandler extends DefaultHandler {
    +37  
    +38      /**
    +39       * The current CPE schema.
    +40       */
    +41      private static final String CURRENT_SCHEMA_VERSION = "2.3";
    +42      /**
    +43       * The text content of the node being processed. This can be used during the end element event.
    +44       */
    +45      private StringBuilder nodeText = null;
    +46      /**
    +47       * A reference to the current element.
    +48       */
    +49      private Element current = new Element();
    +50      /**
    +51       * The logger.
    +52       */
    +53      private static final Logger LOGGER = LoggerFactory.getLogger(NvdCveUpdater.class);
    +54      /**
    +55       * The list of CPE values.
    +56       */
    +57      private List<Cpe> data = new ArrayList<Cpe>();
    +58  
    +59      /**
    +60       * Returns the list of CPE values.
    +61       *
    +62       * @return the list of CPE values
    +63       */
    +64      public List<Cpe> getData() {
    +65          return data;
    +66      }
    +67  
    +68      /**
    +69       * Handles the start element event.
    +70       *
    +71       * @param uri the elements uri
    +72       * @param localName the local name
    +73       * @param qName the qualified name
    +74       * @param attributes the attributes
    +75       * @throws SAXException thrown if there is an exception processing the element
    +76       */
    +77      @Override
    +78      public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
    +79          nodeText = null;
    +80          current.setNode(qName);
    +81          if (current.isCpeItemNode()) {
    +82              final String temp = attributes.getValue("deprecated");
    +83              final String value = attributes.getValue("name");
    +84              final boolean delete = "true".equalsIgnoreCase(temp);
    +85              if (!delete && value.startsWith("cpe:/a:") && value.length() > 7) {
    +86                  try {
    +87                      final Cpe cpe = new Cpe(value);
    +88                      data.add(cpe);
    +89                  } catch (UnsupportedEncodingException ex) {
    +90                      LOGGER.debug("Unable to parse the CPE", ex);
    +91                  } catch (InvalidDataException ex) {
    +92                      LOGGER.debug("CPE is not the correct format", ex);
    +93                  }
    +94              }
    +95          } else if (current.isSchemaVersionNode()) {
    +96              nodeText = new StringBuilder(3);
    +97          }
    +98  //        } else if (current.isTitleNode()) {
    +99  //            //do nothing
    +100 //        } else if (current.isMetaNode()) {
    +101 //            //do nothing
    +102 //        } else if (current.isTimestampNode()) {
    +103 //            //do nothing
    +104 //        } else if (current.isCpeListNode()) {
    +105 //            //do nothing
    +106 //        } else if (current.isNotesNode()) {
    +107 //            //do nothing
    +108 //        } else if (current.isNoteNode()) {
    +109 //            //do nothing
    +110 //        } else if (current.isCheckNode()) {
    +111 //            //do nothing
    +112 //        } else if (current.isGeneratorNode()) {
    +113 //            //do nothing
    +114 //        } else if (current.isProductNameNode()) {
    +115 //            //do nothing
    +116 //        } else if (current.isProductVersionNode()) {
    +117 //            //do nothing
    +118     }
    +119 
    +120     /**
    +121      * Reads the characters in the current node.
    +122      *
    +123      * @param ch the char array
    +124      * @param start the start position of the data read
    +125      * @param length the length of the data read
    +126      * @throws SAXException thrown if there is an exception processing the characters
    +127      */
    +128     @Override
    +129     public void characters(char[] ch, int start, int length) throws SAXException {
    +130         if (nodeText != null) {
    +131             nodeText.append(ch, start, length);
    +132         }
    +133     }
    +134 
    +135     /**
    +136      * Handles the end element event. Stores the CPE data in the Cve Database if the cpe item node is ending.
    +137      *
    +138      * @param uri the element's uri
    +139      * @param localName the local name
    +140      * @param qName the qualified name
    +141      * @throws SAXException thrown if there is an exception processing the element
    +142      */
    +143     @Override
    +144     public void endElement(String uri, String localName, String qName) throws SAXException {
    +145         current.setNode(qName);
    +146         if (current.isSchemaVersionNode() && !CURRENT_SCHEMA_VERSION.equals(nodeText.toString())) {
    +147             throw new SAXException("ERROR: Unexpecgted CPE Schema Version, expected: "
    +148                     + CURRENT_SCHEMA_VERSION + ", file is: " + nodeText);
    +149 
    +150         }
    +151 //        } else if (current.isCpeItemNode()) {
    +152 //            //do nothing
    +153 //        } else if (current.isTitleNode()) {
    +154 //            //do nothing
    +155 //        } else if (current.isCpeListNode()) {
    +156 //            //do nothing
    +157 //        } else if (current.isMetaNode()) {
    +158 //            //do nothing
    +159 //        } else if (current.isNotesNode()) {
    +160 //            //do nothing
    +161 //        } else if (current.isNoteNode()) {
    +162 //            //do nothing
    +163 //        } else if (current.isCheckNode()) {
    +164 //            //do nothing
    +165 //        } else if (current.isGeneratorNode()) {
    +166 //            //do nothing
    +167 //        } else if (current.isProductNameNode()) {
    +168 //            //do nothing
    +169 //        } else if (current.isProductVersionNode()) {
    +170 //            //do nothing
    +171 //        else if (current.isTimestampNode()) {
    +172 //            //do nothing
    +173 //        } else {
    +174 //            throw new SAXException("ERROR STATE: Unexpected qName '" + qName + "'");
    +175 //        }
    +176     }
    +177 
    +178     // <editor-fold defaultstate="collapsed" desc="The Element Class that maintains state information about the current node">
    +179     /**
    +180      * A simple class to maintain information about the current element while parsing the CPE XML.
    +181      */
    +182     protected class Element {
    +183 
    +184         /**
    +185          * A node type in the CPE Schema 2.2
    +186          */
    +187         public static final String CPE_LIST = "cpe-list";
    +188         /**
    +189          * A node type in the CPE Schema 2.2
    +190          */
    +191         public static final String CPE_ITEM = "cpe-item";
    +192         /**
    +193          * A node type in the CPE Schema 2.2
    +194          */
    +195         public static final String TITLE = "title";
    +196         /**
    +197          * A node type in the CPE Schema 2.2
    +198          */
    +199         public static final String NOTES = "notes";
    +200         /**
    +201          * A node type in the CPE Schema 2.2
    +202          */
    +203         public static final String NOTE = "note";
    +204         /**
    +205          * A node type in the CPE Schema 2.2
    +206          */
    +207         public static final String CHECK = "check";
    +208         /**
    +209          * A node type in the CPE Schema 2.2
    +210          */
    +211         public static final String META = "meta:item-metadata";
    +212         /**
    +213          * A node type in the CPE Schema 2.2
    +214          */
    +215         public static final String GENERATOR = "generator";
    +216         /**
    +217          * A node type in the CPE Schema 2.2
    +218          */
    +219         public static final String PRODUCT_NAME = "product_name";
    +220         /**
    +221          * A node type in the CPE Schema 2.2
    +222          */
    +223         public static final String PRODUCT_VERSION = "product_version";
    +224         /**
    +225          * A node type in the CPE Schema 2.2
    +226          */
    +227         public static final String SCHEMA_VERSION = "schema_version";
    +228         /**
    +229          * A node type in the CPE Schema 2.2
    +230          */
    +231         public static final String TIMESTAMP = "timestamp";
    +232         /**
    +233          * A reference to the current node.
    +234          */
    +235         private String node = null;
    +236 
    +237         /**
    +238          * Gets the value of node
    +239          *
    +240          * @return the value of node
    +241          */
    +242         public String getNode() {
    +243             return this.node;
    +244         }
    +245 
    +246         /**
    +247          * Sets the value of node
    +248          *
    +249          * @param node new value of node
    +250          */
    +251         public void setNode(String node) {
    +252             this.node = node;
    +253         }
    +254 
    +255         /**
    +256          * Checks if the handler is at the CPE_LIST node
    +257          *
    +258          * @return true or false
    +259          */
    +260         public boolean isCpeListNode() {
    +261             return CPE_LIST.equals(node);
    +262         }
    +263 
    +264         /**
    +265          * Checks if the handler is at the CPE_ITEM node
    +266          *
    +267          * @return true or false
    +268          */
    +269         public boolean isCpeItemNode() {
    +270             return CPE_ITEM.equals(node);
    +271         }
    +272 
    +273         /**
    +274          * Checks if the handler is at the TITLE node
    +275          *
    +276          * @return true or false
    +277          */
    +278         public boolean isTitleNode() {
    +279             return TITLE.equals(node);
    +280         }
    +281 
    +282         /**
    +283          * Checks if the handler is at the NOTES node
    +284          *
    +285          * @return true or false
    +286          */
    +287         public boolean isNotesNode() {
    +288             return NOTES.equals(node);
    +289         }
    +290 
    +291         /**
    +292          * Checks if the handler is at the NOTE node
    +293          *
    +294          * @return true or false
    +295          */
    +296         public boolean isNoteNode() {
    +297             return NOTE.equals(node);
    +298         }
    +299 
    +300         /**
    +301          * Checks if the handler is at the CHECK node
    +302          *
    +303          * @return true or false
    +304          */
    +305         public boolean isCheckNode() {
    +306             return CHECK.equals(node);
    +307         }
    +308 
    +309         /**
    +310          * Checks if the handler is at the META node
    +311          *
    +312          * @return true or false
    +313          */
    +314         public boolean isMetaNode() {
    +315             return META.equals(node);
    +316         }
    +317 
    +318         /**
    +319          * Checks if the handler is at the GENERATOR node
    +320          *
    +321          * @return true or false
    +322          */
    +323         public boolean isGeneratorNode() {
    +324             return GENERATOR.equals(node);
    +325         }
    +326 
    +327         /**
    +328          * Checks if the handler is at the PRODUCT_NAME node
    +329          *
    +330          * @return true or false
    +331          */
    +332         public boolean isProductNameNode() {
    +333             return PRODUCT_NAME.equals(node);
    +334         }
    +335 
    +336         /**
    +337          * Checks if the handler is at the PRODUCT_VERSION node
    +338          *
    +339          * @return true or false
    +340          */
    +341         public boolean isProductVersionNode() {
    +342             return PRODUCT_VERSION.equals(node);
    +343         }
    +344 
    +345         /**
    +346          * Checks if the handler is at the SCHEMA_VERSION node
    +347          *
    +348          * @return true or false
    +349          */
    +350         public boolean isSchemaVersionNode() {
    +351             return SCHEMA_VERSION.equals(node);
    +352         }
    +353 
    +354         /**
    +355          * Checks if the handler is at the TIMESTAMP node
    +356          *
    +357          * @return true or false
    +358          */
    +359         public boolean isTimestampNode() {
    +360             return TIMESTAMP.equals(node);
    +361         }
    +362     }
    +363     // </editor-fold>
    +364 }
    +
    +
    + + + diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/cpe/Cpe.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/cpe/Cpe.html new file mode 100644 index 000000000..b3da9bc35 --- /dev/null +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/cpe/Cpe.html @@ -0,0 +1,138 @@ + + + +Cpe 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) 2015 Jeremy Long. All Rights Reserved.
    +17   */
    +18  package org.owasp.dependencycheck.data.update.cpe;
    +19  
    +20  import java.io.UnsupportedEncodingException;
    +21  import java.net.URLDecoder;
    +22  import org.owasp.dependencycheck.data.update.exception.InvalidDataException;
    +23  
    +24  /**
    +25   *
    +26   * @author Jeremy Long
    +27   */
    +28  public class Cpe {
    +29  
    +30      /**
    +31       * Constructs a new Cpe Object by parsing the vendor and product from the CPE identifier value.
    +32       *
    +33       * @param value the cpe identifier (cpe:/a:vendor:product:version:....)
    +34       * @throws UnsupportedEncodingException thrown if UTF-8 is not supported
    +35       * @throws InvalidDataException thrown if the CPE provided is not the correct format
    +36       */
    +37      public Cpe(String value) throws UnsupportedEncodingException, InvalidDataException {
    +38          this.value = value;
    +39          final String[] data = value.substring(7).split(":");
    +40          if (data.length >= 2) {
    +41              vendor = URLDecoder.decode(data[0].replace("+", "%2B"), "UTF-8");
    +42              product = URLDecoder.decode(data[1].replace("+", "%2B"), "UTF-8");
    +43          } else {
    +44              throw new InvalidDataException(String.format("CPE has an invalid format: %s", value));
    +45          }
    +46      }
    +47  
    +48      /**
    +49       * The CPE identifier string (cpe:/a:vendor:product:version).
    +50       */
    +51      private String value;
    +52  
    +53      /**
    +54       * Get the value of value.
    +55       *
    +56       * @return the value of value
    +57       */
    +58      public String getValue() {
    +59          return value;
    +60      }
    +61  
    +62      /**
    +63       * Set the value of value.
    +64       *
    +65       * @param value new value of value
    +66       */
    +67      public void setValue(String value) {
    +68          this.value = value;
    +69      }
    +70      /**
    +71       * The vendor portion of the identifier.
    +72       */
    +73      private String vendor;
    +74  
    +75      /**
    +76       * Get the value of vendor.
    +77       *
    +78       * @return the value of vendor
    +79       */
    +80      public String getVendor() {
    +81          return vendor;
    +82      }
    +83  
    +84      /**
    +85       * Set the value of vendor.
    +86       *
    +87       * @param vendor new value of vendor
    +88       */
    +89      public void setVendor(String vendor) {
    +90          this.vendor = vendor;
    +91      }
    +92  
    +93      /**
    +94       * The product portion of the identifier.
    +95       */
    +96      private String product;
    +97  
    +98      /**
    +99       * Get the value of product.
    +100      *
    +101      * @return the value of product
    +102      */
    +103     public String getProduct() {
    +104         return product;
    +105     }
    +106 
    +107     /**
    +108      * Set the value of product.
    +109      *
    +110      * @param product new value of product
    +111      */
    +112     public void setProduct(String product) {
    +113         this.product = product;
    +114     }
    +115 
    +116     /**
    +117      * Returns the full CPE identifier.
    +118      *
    +119      * @return the full CPE identifier
    +120      */
    +121     @Override
    +122     public String toString() {
    +123         return value;
    +124     }
    +125 }
    +
    +
    + + + 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 new file mode 100644 index 000000000..f1f1009ab --- /dev/null +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/cpe/package-frame.html @@ -0,0 +1,30 @@ + + + + + + Dependency-Check Core 1.3.0 Reference Package org.owasp.dependencycheck.data.update.cpe + + + + +

    + org.owasp.dependencycheck.data.update.cpe +

    + +

    Classes

    + + + + + \ No newline at end of file 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 new file mode 100644 index 000000000..d0b920a6c --- /dev/null +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/cpe/package-summary.html @@ -0,0 +1,79 @@ + + + + + + Dependency-Check Core 1.3.0 Reference Package org.owasp.dependencycheck.data.update.cpe + + + +
    + +
    +
    + +
    + +

    Package org.owasp.dependencycheck.data.update.cpe

    + + + + + + + + + + + + + + + + + + +
    Class Summary
    + CPEHandler +
    + Cpe +
    + Element +
    + +
    + +
    +
    + +
    +
    + + + \ No newline at end of file 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 7847c126f..bd38f1495 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.2.11 Reference Package org.owasp.dependencycheck.data.update.exception + Dependency-Check Core 1.3.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 4d75d190c..75d4f0ca0 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.2.11 Reference Package org.owasp.dependencycheck.data.update.exception + Dependency-Check Core 1.3.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 new file mode 100644 index 000000000..6dc8c8c7f --- /dev/null +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/DownloadTask.html @@ -0,0 +1,312 @@ + + + +DownloadTask 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.data.update.nvd;
    +19  
    +20  import java.io.File;
    +21  import java.io.FileInputStream;
    +22  import java.io.FileNotFoundException;
    +23  import java.io.FileOutputStream;
    +24  import java.io.IOException;
    +25  import java.net.URL;
    +26  import java.util.concurrent.Callable;
    +27  import java.util.concurrent.ExecutorService;
    +28  import java.util.concurrent.Future;
    +29  import java.util.zip.GZIPInputStream;
    +30  import org.apache.commons.io.FileUtils;
    +31  import org.owasp.dependencycheck.data.nvdcve.CveDB;
    +32  import org.owasp.dependencycheck.data.update.exception.UpdateException;
    +33  import org.owasp.dependencycheck.utils.DownloadFailedException;
    +34  import org.owasp.dependencycheck.utils.Downloader;
    +35  import org.owasp.dependencycheck.utils.Settings;
    +36  import org.slf4j.Logger;
    +37  import org.slf4j.LoggerFactory;
    +38  
    +39  /**
    +40   * A callable object to download two files.
    +41   *
    +42   * @author Jeremy Long
    +43   */
    +44  public class DownloadTask implements Callable<Future<ProcessTask>> {
    +45  
    +46      /**
    +47       * The Logger.
    +48       */
    +49      private static final Logger LOGGER = LoggerFactory.getLogger(DownloadTask.class);
    +50  
    +51      /**
    +52       * Simple constructor for the callable download task.
    +53       *
    +54       * @param nvdCveInfo the NVD CVE info
    +55       * @param processor the processor service to submit the downloaded files to
    +56       * @param cveDB the CVE DB to use to store the vulnerability data
    +57       * @param settings a reference to the global settings object; this is necessary so that when the thread is started the
    +58       * dependencies have a correct reference to the global settings.
    +59       * @throws UpdateException thrown if temporary files could not be created
    +60       */
    +61      public DownloadTask(NvdCveInfo nvdCveInfo, ExecutorService processor, CveDB cveDB, Settings settings) throws UpdateException {
    +62          this.nvdCveInfo = nvdCveInfo;
    +63          this.processorService = processor;
    +64          this.cveDB = cveDB;
    +65          this.settings = settings;
    +66  
    +67          final File file1;
    +68          final File file2;
    +69  
    +70          try {
    +71              file1 = File.createTempFile("cve" + nvdCveInfo.getId() + "_", ".xml", Settings.getTempDirectory());
    +72              file2 = File.createTempFile("cve_1_2_" + nvdCveInfo.getId() + "_", ".xml", Settings.getTempDirectory());
    +73          } catch (IOException ex) {
    +74              throw new UpdateException("Unable to create temporary files", ex);
    +75          }
    +76          this.first = file1;
    +77          this.second = file2;
    +78  
    +79      }
    +80      /**
    +81       * The CVE DB to use when processing the files.
    +82       */
    +83      private CveDB cveDB;
    +84      /**
    +85       * The processor service to pass the results of the download to.
    +86       */
    +87      private ExecutorService processorService;
    +88      /**
    +89       * The NVD CVE Meta Data.
    +90       */
    +91      private NvdCveInfo nvdCveInfo;
    +92      /**
    +93       * A reference to the global settings object.
    +94       */
    +95      private Settings settings;
    +96  
    +97      /**
    +98       * Get the value of nvdCveInfo.
    +99       *
    +100      * @return the value of nvdCveInfo
    +101      */
    +102     public NvdCveInfo getNvdCveInfo() {
    +103         return nvdCveInfo;
    +104     }
    +105 
    +106     /**
    +107      * Set the value of nvdCveInfo.
    +108      *
    +109      * @param nvdCveInfo new value of nvdCveInfo
    +110      */
    +111     public void setNvdCveInfo(NvdCveInfo nvdCveInfo) {
    +112         this.nvdCveInfo = nvdCveInfo;
    +113     }
    +114     /**
    +115      * a file.
    +116      */
    +117     private File first;
    +118 
    +119     /**
    +120      * Get the value of first.
    +121      *
    +122      * @return the value of first
    +123      */
    +124     public File getFirst() {
    +125         return first;
    +126     }
    +127 
    +128     /**
    +129      * Set the value of first.
    +130      *
    +131      * @param first new value of first
    +132      */
    +133     public void setFirst(File first) {
    +134         this.first = first;
    +135     }
    +136     /**
    +137      * a file.
    +138      */
    +139     private File second;
    +140 
    +141     /**
    +142      * Get the value of second.
    +143      *
    +144      * @return the value of second
    +145      */
    +146     public File getSecond() {
    +147         return second;
    +148     }
    +149 
    +150     /**
    +151      * Set the value of second.
    +152      *
    +153      * @param second new value of second
    +154      */
    +155     public void setSecond(File second) {
    +156         this.second = second;
    +157     }
    +158     /**
    +159      * A placeholder for an exception.
    +160      */
    +161     private Exception exception = null;
    +162 
    +163     /**
    +164      * Get the value of exception.
    +165      *
    +166      * @return the value of exception
    +167      */
    +168     public Exception getException() {
    +169         return exception;
    +170     }
    +171 
    +172     /**
    +173      * returns whether or not an exception occurred during download.
    +174      *
    +175      * @return whether or not an exception occurred during download
    +176      */
    +177     public boolean hasException() {
    +178         return exception != null;
    +179     }
    +180 
    +181     @Override
    +182     public Future<ProcessTask> call() throws Exception {
    +183         try {
    +184             Settings.setInstance(settings);
    +185             final URL url1 = new URL(nvdCveInfo.getUrl());
    +186             final URL url2 = new URL(nvdCveInfo.getOldSchemaVersionUrl());
    +187             LOGGER.info("Download Started for NVD CVE - {}", nvdCveInfo.getId());
    +188             try {
    +189                 Downloader.fetchFile(url1, first);
    +190                 Downloader.fetchFile(url2, second);
    +191             } catch (DownloadFailedException ex) {
    +192                 LOGGER.warn("Download Failed for NVD CVE - {}\nSome CVEs may not be reported.", nvdCveInfo.getId());
    +193                 if (Settings.getString(Settings.KEYS.PROXY_SERVER) == null) {
    +194                     LOGGER.info(
    +195                             "If you are behind a proxy you may need to configure dependency-check to use the proxy.");
    +196                 }
    +197                 LOGGER.debug("", ex);
    +198                 return null;
    +199             }
    +200             if (url1.toExternalForm().endsWith(".xml.gz")) {
    +201                 extractGzip(first);
    +202             }
    +203             if (url2.toExternalForm().endsWith(".xml.gz")) {
    +204                 extractGzip(second);
    +205             }
    +206 
    +207             LOGGER.info("Download Complete for NVD CVE - {}", nvdCveInfo.getId());
    +208             if (this.processorService == null) {
    +209                 return null;
    +210             }
    +211             final ProcessTask task = new ProcessTask(cveDB, this, settings);
    +212             return this.processorService.submit(task);
    +213 
    +214         } catch (Throwable ex) {
    +215             LOGGER.warn("An exception occurred downloading NVD CVE - {}\nSome CVEs may not be reported.", nvdCveInfo.getId());
    +216             LOGGER.debug("Download Task Failed", ex);
    +217         } finally {
    +218             Settings.cleanup(false);
    +219         }
    +220         return null;
    +221     }
    +222 
    +223     /**
    +224      * Attempts to delete the files that were downloaded.
    +225      */
    +226     public void cleanup() {
    +227         boolean deleted = false;
    +228         try {
    +229             if (first != null && first.exists()) {
    +230                 deleted = first.delete();
    +231             }
    +232         } finally {
    +233             if (first != null && (first.exists() || !deleted)) {
    +234                 first.deleteOnExit();
    +235             }
    +236         }
    +237         try {
    +238             deleted = false;
    +239             if (second != null && second.exists()) {
    +240                 deleted = second.delete();
    +241             }
    +242         } finally {
    +243             if (second != null && (second.exists() || !deleted)) {
    +244                 second.deleteOnExit();
    +245             }
    +246         }
    +247     }
    +248 
    +249     /**
    +250      * Extracts the file contained in a gzip archive. The extracted file is placed in the exact same path as the file specified.
    +251      *
    +252      * @param file the archive file
    +253      * @throws FileNotFoundException thrown if the file does not exist
    +254      * @throws IOException thrown if there is an error extracting the file.
    +255      */
    +256     private void extractGzip(File file) throws FileNotFoundException, IOException {
    +257         final String originalPath = file.getPath();
    +258         final File gzip = new File(originalPath + ".gz");
    +259         if (gzip.isFile() && !gzip.delete()) {
    +260             gzip.deleteOnExit();
    +261         }
    +262         if (!file.renameTo(gzip)) {
    +263             throw new IOException("Unable to rename '" + file.getPath() + "'");
    +264         }
    +265         final File newfile = new File(originalPath);
    +266 
    +267         final byte[] buffer = new byte[4096];
    +268 
    +269         GZIPInputStream cin = null;
    +270         FileOutputStream out = null;
    +271         try {
    +272             cin = new GZIPInputStream(new FileInputStream(gzip));
    +273             out = new FileOutputStream(newfile);
    +274 
    +275             int len;
    +276             while ((len = cin.read(buffer)) > 0) {
    +277                 out.write(buffer, 0, len);
    +278             }
    +279         } finally {
    +280             if (cin != null) {
    +281                 try {
    +282                     cin.close();
    +283                 } catch (IOException ex) {
    +284                     LOGGER.trace("ignore", ex);
    +285                 }
    +286             }
    +287             if (out != null) {
    +288                 try {
    +289                     out.close();
    +290                 } catch (IOException ex) {
    +291                     LOGGER.trace("ignore", ex);
    +292                 }
    +293             }
    +294             if (gzip.isFile()) {
    +295                 FileUtils.deleteQuietly(gzip);
    +296             }
    +297         }
    +298     }
    +299 }
    +
    +
    + + + diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/NvdCve12Handler.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/NvdCve12Handler.html new file mode 100644 index 000000000..f0cad8fd9 --- /dev/null +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/NvdCve12Handler.html @@ -0,0 +1,256 @@ + + + +NvdCve12Handler 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) 2012 Jeremy Long. All Rights Reserved.
    +17   */
    +18  package org.owasp.dependencycheck.data.update.nvd;
    +19  
    +20  import java.util.ArrayList;
    +21  import java.util.HashMap;
    +22  import java.util.List;
    +23  import java.util.Map;
    +24  import org.owasp.dependencycheck.dependency.VulnerableSoftware;
    +25  import org.xml.sax.Attributes;
    +26  import org.xml.sax.SAXException;
    +27  import org.xml.sax.SAXNotSupportedException;
    +28  import org.xml.sax.helpers.DefaultHandler;
    +29  
    +30  /**
    +31   * A SAX Handler that will parse the NVD CVE XML (schema version 1.2). This parses the xml and retrieves a listing of
    +32   * CPEs that have previous versions specified. The previous version information is not in the 2.0 version of the schema
    +33   * and is useful to ensure accurate identification (or at least complete).
    +34   *
    +35   * @author Jeremy Long
    +36   */
    +37  public class NvdCve12Handler extends DefaultHandler {
    +38  
    +39      /**
    +40       * the supported schema version.
    +41       */
    +42      private static final String CURRENT_SCHEMA_VERSION = "1.2";
    +43      /**
    +44       * the current vulnerability.
    +45       */
    +46      private String vulnerability;
    +47      /**
    +48       * a list of vulnerable software.
    +49       */
    +50      private List<VulnerableSoftware> software;
    +51      /**
    +52       * the vendor name.
    +53       */
    +54      private String vendor;
    +55      /**
    +56       * the product name.
    +57       */
    +58      private String product;
    +59      /**
    +60       * if the nvd cve should be skipped because it was rejected.
    +61       */
    +62      private boolean skip = false;
    +63      /**
    +64       * flag indicating if there is a previous version.
    +65       */
    +66      private boolean hasPreviousVersion = false;
    +67      /**
    +68       * The current element.
    +69       */
    +70      private final Element current = new Element();
    +71      /**
    +72       * a map of vulnerabilities.
    +73       */
    +74      private Map<String, List<VulnerableSoftware>> vulnerabilities;
    +75  
    +76      /**
    +77       * Get the value of vulnerabilities.
    +78       *
    +79       * @return the value of vulnerabilities
    +80       */
    +81      public Map<String, List<VulnerableSoftware>> getVulnerabilities() {
    +82          return vulnerabilities;
    +83      }
    +84  
    +85      @Override
    +86      public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
    +87          current.setNode(qName);
    +88          if (current.isEntryNode()) {
    +89              vendor = null;
    +90              product = null;
    +91              hasPreviousVersion = false;
    +92              final String reject = attributes.getValue("reject");
    +93              skip = "1".equals(reject);
    +94              if (!skip) {
    +95                  vulnerability = attributes.getValue("name");
    +96                  software = new ArrayList<VulnerableSoftware>();
    +97              } else {
    +98                  vulnerability = null;
    +99                  software = null;
    +100             }
    +101         } else if (!skip && current.isProdNode()) {
    +102 
    +103             vendor = attributes.getValue("vendor");
    +104             product = attributes.getValue("name");
    +105         } else if (!skip && current.isVersNode()) {
    +106             final String prev = attributes.getValue("prev");
    +107             if (prev != null && "1".equals(prev)) {
    +108                 hasPreviousVersion = true;
    +109                 final String edition = attributes.getValue("edition");
    +110                 final String num = attributes.getValue("num");
    +111 
    +112                 /*yes yes, this may not actually be an "a" - it could be an OS, etc. but for our
    +113                  purposes this is good enough as we won't use this if we don't find a corresponding "a"
    +114                  in the nvd cve 2.0. */
    +115                 String cpe = "cpe:/a:" + vendor + ":" + product;
    +116                 if (num != null) {
    +117                     cpe += ":" + num;
    +118                 }
    +119                 if (edition != null) {
    +120                     cpe += ":" + edition;
    +121                 }
    +122                 final VulnerableSoftware vs = new VulnerableSoftware();
    +123                 vs.setCpe(cpe);
    +124                 vs.setPreviousVersion(prev);
    +125                 software.add(vs);
    +126             }
    +127         } else if (current.isNVDNode()) {
    +128             final String nvdVer = attributes.getValue("nvd_xml_version");
    +129             if (!CURRENT_SCHEMA_VERSION.equals(nvdVer)) {
    +130                 throw new SAXNotSupportedException("Schema version " + nvdVer + " is not supported");
    +131             }
    +132             vulnerabilities = new HashMap<String, List<VulnerableSoftware>>();
    +133         }
    +134     }
    +135 
    +136     @Override
    +137     public void endElement(String uri, String localName, String qName) throws SAXException {
    +138         current.setNode(qName);
    +139         if (current.isEntryNode()) {
    +140             if (!skip && hasPreviousVersion) {
    +141                 vulnerabilities.put(vulnerability, software);
    +142             }
    +143             vulnerability = null;
    +144             software = null;
    +145         }
    +146     }
    +147 
    +148     // <editor-fold defaultstate="collapsed" desc="The Element Class that maintains state information about the current node">
    +149     /**
    +150      * A simple class to maintain information about the current element while parsing the NVD CVE XML.
    +151      */
    +152     protected static class Element {
    +153 
    +154         /**
    +155          * A node type in the NVD CVE Schema 1.2.
    +156          */
    +157         public static final String NVD = "nvd";
    +158         /**
    +159          * A node type in the NVD CVE Schema 1.2.
    +160          */
    +161         public static final String ENTRY = "entry";
    +162         /**
    +163          * A node type in the NVD CVE Schema 1.2.
    +164          */
    +165         public static final String VULN_SOFTWARE = "vuln_soft";
    +166         /**
    +167          * A node type in the NVD CVE Schema 1.2.
    +168          */
    +169         public static final String PROD = "prod";
    +170         /**
    +171          * A node type in the NVD CVE Schema 1.2.
    +172          */
    +173         public static final String VERS = "vers";
    +174         /**
    +175          * The name of the current node.
    +176          */
    +177         private String node;
    +178 
    +179         /**
    +180          * Gets the value of node.
    +181          *
    +182          * @return the value of node
    +183          */
    +184         public String getNode() {
    +185             return this.node;
    +186         }
    +187 
    +188         /**
    +189          * Sets the value of node.
    +190          *
    +191          * @param node new value of node
    +192          */
    +193         public void setNode(String node) {
    +194             this.node = node;
    +195         }
    +196 
    +197         /**
    +198          * Checks if the handler is at the NVD node.
    +199          *
    +200          * @return true or false
    +201          */
    +202         public boolean isNVDNode() {
    +203             return NVD.equals(node);
    +204         }
    +205 
    +206         /**
    +207          * Checks if the handler is at the ENTRY node.
    +208          *
    +209          * @return true or false
    +210          */
    +211         public boolean isEntryNode() {
    +212             return ENTRY.equals(node);
    +213         }
    +214 
    +215         /**
    +216          * Checks if the handler is at the VULN_SOFTWARE node.
    +217          *
    +218          * @return true or false
    +219          */
    +220         public boolean isVulnSoftwareNode() {
    +221             return VULN_SOFTWARE.equals(node);
    +222         }
    +223 
    +224         /**
    +225          * Checks if the handler is at the PROD node.
    +226          *
    +227          * @return true or false
    +228          */
    +229         public boolean isProdNode() {
    +230             return PROD.equals(node);
    +231         }
    +232 
    +233         /**
    +234          * Checks if the handler is at the VERS node.
    +235          *
    +236          * @return true or false
    +237          */
    +238         public boolean isVersNode() {
    +239             return VERS.equals(node);
    +240         }
    +241     }
    +242     // </editor-fold>
    +243 }
    +
    +
    + + + 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 new file mode 100644 index 000000000..9bc66db89 --- /dev/null +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/NvdCve20Handler.html @@ -0,0 +1,508 @@ + + + +NvdCve20Handler 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) 2012 Jeremy Long. All Rights Reserved.
    +17   */
    +18  package org.owasp.dependencycheck.data.update.nvd;
    +19  
    +20  import java.io.IOException;
    +21  import java.util.List;
    +22  import java.util.Map;
    +23  import org.apache.lucene.index.CorruptIndexException;
    +24  import org.owasp.dependencycheck.data.nvdcve.CveDB;
    +25  import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
    +26  import org.owasp.dependencycheck.dependency.Reference;
    +27  import org.owasp.dependencycheck.dependency.Vulnerability;
    +28  import org.owasp.dependencycheck.dependency.VulnerableSoftware;
    +29  import org.slf4j.Logger;
    +30  import org.slf4j.LoggerFactory;
    +31  import org.xml.sax.Attributes;
    +32  import org.xml.sax.SAXException;
    +33  import org.xml.sax.SAXNotSupportedException;
    +34  import org.xml.sax.helpers.DefaultHandler;
    +35  
    +36  /**
    +37   * A SAX Handler that will parse the NVD CVE XML (schema version 2.0).
    +38   *
    +39   * @author Jeremy Long
    +40   */
    +41  public class NvdCve20Handler extends DefaultHandler {
    +42  
    +43      /**
    +44       * The logger.
    +45       */
    +46      private static final Logger LOGGER = LoggerFactory.getLogger(NvdCve20Handler.class);
    +47      /**
    +48       * the current supported schema version.
    +49       */
    +50      private static final String CURRENT_SCHEMA_VERSION = "2.0";
    +51      /**
    +52       * the current element.
    +53       */
    +54      private final Element current = new Element();
    +55      /**
    +56       * the text of the node.
    +57       */
    +58      private StringBuilder nodeText;
    +59      /**
    +60       * the vulnerability.
    +61       */
    +62      private Vulnerability vulnerability;
    +63      /**
    +64       * a reference for the cve.
    +65       */
    +66      private Reference reference;
    +67      /**
    +68       * flag indicating whether the application has a cpe.
    +69       */
    +70      private boolean hasApplicationCpe = false;
    +71      /**
    +72       * The total number of entries parsed.
    +73       */
    +74      private int totalNumberOfEntries;
    +75  
    +76      /**
    +77       * Get the value of totalNumberOfEntries.
    +78       *
    +79       * @return the value of totalNumberOfEntries
    +80       */
    +81      public int getTotalNumberOfEntries() {
    +82          return totalNumberOfEntries;
    +83      }
    +84      /**
    +85       * The total number of application entries parsed.
    +86       */
    +87      private int totalNumberOfApplicationEntries;
    +88  
    +89      /**
    +90       * Get the value of totalNumberOfApplicationEntries.
    +91       *
    +92       * @return the value of totalNumberOfApplicationEntries
    +93       */
    +94      public int getTotalNumberOfApplicationEntries() {
    +95          return totalNumberOfApplicationEntries;
    +96      }
    +97  
    +98      @Override
    +99      public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
    +100         current.setNode(qName);
    +101         if (current.isEntryNode()) {
    +102             hasApplicationCpe = false;
    +103             vulnerability = new Vulnerability();
    +104             vulnerability.setName(attributes.getValue("id"));
    +105         } else if (current.isVulnProductNode()) {
    +106             nodeText = new StringBuilder(100);
    +107         } else if (current.isVulnReferencesNode()) {
    +108             final String lang = attributes.getValue("xml:lang");
    +109             if ("en".equals(lang)) {
    +110                 reference = new Reference();
    +111             } else {
    +112                 reference = null;
    +113             }
    +114         } else if (reference != null && current.isVulnReferenceNode()) {
    +115             reference.setUrl(attributes.getValue("href"));
    +116             nodeText = new StringBuilder(130);
    +117         } else if (reference != null && current.isVulnSourceNode()) {
    +118             nodeText = new StringBuilder(30);
    +119         } else if (current.isVulnSummaryNode()) {
    +120             nodeText = new StringBuilder(500);
    +121         } else if (current.isNVDNode()) {
    +122             final String nvdVer = attributes.getValue("nvd_xml_version");
    +123             if (!CURRENT_SCHEMA_VERSION.equals(nvdVer)) {
    +124                 throw new SAXNotSupportedException("Schema version " + nvdVer + " is not supported");
    +125             }
    +126         } else if (current.isVulnCWENode()) {
    +127             vulnerability.setCwe(attributes.getValue("id"));
    +128         } else if (current.isCVSSScoreNode()) {
    +129             nodeText = new StringBuilder(5);
    +130         } else if (current.isCVSSAccessVectorNode()) {
    +131             nodeText = new StringBuilder(20);
    +132         } else if (current.isCVSSAccessComplexityNode()) {
    +133             nodeText = new StringBuilder(20);
    +134         } else if (current.isCVSSAuthenticationNode()) {
    +135             nodeText = new StringBuilder(20);
    +136         } else if (current.isCVSSAvailabilityImpactNode()) {
    +137             nodeText = new StringBuilder(20);
    +138         } else if (current.isCVSSConfidentialityImpactNode()) {
    +139             nodeText = new StringBuilder(20);
    +140         } else if (current.isCVSSIntegrityImpactNode()) {
    +141             nodeText = new StringBuilder(20);
    +142         }
    +143     }
    +144 
    +145     @Override
    +146     public void characters(char[] ch, int start, int length) throws SAXException {
    +147         if (nodeText != null) {
    +148             nodeText.append(ch, start, length);
    +149         }
    +150     }
    +151 
    +152     @Override
    +153     public void endElement(String uri, String localName, String qName) throws SAXException {
    +154         current.setNode(qName);
    +155         if (current.isEntryNode()) {
    +156             totalNumberOfEntries += 1;
    +157             if (hasApplicationCpe) {
    +158                 totalNumberOfApplicationEntries += 1;
    +159                 try {
    +160                     saveEntry(vulnerability);
    +161                 } catch (DatabaseException ex) {
    +162                     throw new SAXException(ex);
    +163                 } catch (CorruptIndexException ex) {
    +164                     throw new SAXException(ex);
    +165                 } catch (IOException ex) {
    +166                     throw new SAXException(ex);
    +167                 }
    +168             }
    +169             vulnerability = null;
    +170         } else if (current.isCVSSScoreNode()) {
    +171             try {
    +172                 final float score = Float.parseFloat(nodeText.toString());
    +173                 vulnerability.setCvssScore(score);
    +174             } catch (NumberFormatException ex) {
    +175                 LOGGER.error("Error parsing CVSS Score.");
    +176                 LOGGER.debug("", ex);
    +177             }
    +178             nodeText = null;
    +179         } else if (current.isCVSSAccessVectorNode()) {
    +180             vulnerability.setCvssAccessVector(nodeText.toString());
    +181             nodeText = null;
    +182         } else if (current.isCVSSAccessComplexityNode()) {
    +183             vulnerability.setCvssAccessComplexity(nodeText.toString());
    +184             nodeText = null;
    +185         } else if (current.isCVSSAuthenticationNode()) {
    +186             vulnerability.setCvssAuthentication(nodeText.toString());
    +187             nodeText = null;
    +188         } else if (current.isCVSSAvailabilityImpactNode()) {
    +189             vulnerability.setCvssAvailabilityImpact(nodeText.toString());
    +190             nodeText = null;
    +191         } else if (current.isCVSSConfidentialityImpactNode()) {
    +192             vulnerability.setCvssConfidentialityImpact(nodeText.toString());
    +193             nodeText = null;
    +194         } else if (current.isCVSSIntegrityImpactNode()) {
    +195             vulnerability.setCvssIntegrityImpact(nodeText.toString());
    +196             nodeText = null;
    +197         } else if (current.isVulnProductNode()) {
    +198             final String cpe = nodeText.toString();
    +199             if (cpe.startsWith("cpe:/a:")) {
    +200                 hasApplicationCpe = true;
    +201                 vulnerability.addVulnerableSoftware(cpe);
    +202             }
    +203             nodeText = null;
    +204         } else if (reference != null && current.isVulnReferencesNode()) {
    +205             vulnerability.addReference(reference);
    +206             reference = null;
    +207         } else if (reference != null && current.isVulnReferenceNode()) {
    +208             reference.setName(nodeText.toString());
    +209             nodeText = null;
    +210         } else if (reference != null && current.isVulnSourceNode()) {
    +211             reference.setSource(nodeText.toString());
    +212             nodeText = null;
    +213         } else if (current.isVulnSummaryNode()) {
    +214             vulnerability.setDescription(nodeText.toString());
    +215             if (nodeText.indexOf("** REJECT **") >= 0) {
    +216                 hasApplicationCpe = true; //ensure we process this to delete the vuln
    +217             }
    +218             nodeText = null;
    +219         }
    +220     }
    +221     /**
    +222      * the cve database.
    +223      */
    +224     private CveDB cveDB;
    +225 
    +226     /**
    +227      * Sets the cveDB.
    +228      *
    +229      * @param db a reference to the CveDB
    +230      */
    +231     public void setCveDB(CveDB db) {
    +232         cveDB = db;
    +233     }
    +234     /**
    +235      * A list of CVE entries and associated VulnerableSoftware entries that contain previous entries.
    +236      */
    +237     private Map<String, List<VulnerableSoftware>> prevVersionVulnMap;
    +238 
    +239     /**
    +240      * Sets the prevVersionVulnMap.
    +241      *
    +242      * @param map the map of vulnerable software with previous versions being vulnerable
    +243      */
    +244     public void setPrevVersionVulnMap(Map<String, List<VulnerableSoftware>> map) {
    +245         prevVersionVulnMap = map;
    +246     }
    +247 
    +248     /**
    +249      * Saves a vulnerability to the CVE Database.
    +250      *
    +251      * @param vuln the vulnerability to store in the database
    +252      * @throws DatabaseException thrown if there is an error writing to the database
    +253      * @throws CorruptIndexException is thrown if the CPE Index is corrupt
    +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             }
    +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 }
    +
    +
    + + + diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/NvdCveInfo.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/NvdCveInfo.html new file mode 100644 index 000000000..4089f2242 --- /dev/null +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/NvdCveInfo.html @@ -0,0 +1,150 @@ + + + +NvdCveInfo 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.data.update.nvd;
    +19  
    +20  /**
    +21   * A pojo that contains the Url and timestamp of the current NvdCve XML files.
    +22   *
    +23   * @author Jeremy Long
    +24   */
    +25  public class NvdCveInfo {
    +26  
    +27      /**
    +28       * an id.
    +29       */
    +30      private String id;
    +31  
    +32      /**
    +33       * Get the value of id.
    +34       *
    +35       * @return the value of id
    +36       */
    +37      public String getId() {
    +38          return id;
    +39      }
    +40  
    +41      /**
    +42       * Set the value of id.
    +43       *
    +44       * @param id new value of id
    +45       */
    +46      public void setId(String id) {
    +47          this.id = id;
    +48      }
    +49      /**
    +50       * a url.
    +51       */
    +52      private String url;
    +53  
    +54      /**
    +55       * Get the value of url.
    +56       *
    +57       * @return the value of url
    +58       */
    +59      public String getUrl() {
    +60          return url;
    +61      }
    +62  
    +63      /**
    +64       * Set the value of url.
    +65       *
    +66       * @param url new value of url
    +67       */
    +68      public void setUrl(String url) {
    +69          this.url = url;
    +70      }
    +71      /**
    +72       * The 1.2 schema URL.
    +73       */
    +74      private String oldSchemaVersionUrl;
    +75  
    +76      /**
    +77       * Get the value of oldSchemaVersionUrl.
    +78       *
    +79       * @return the value of oldSchemaVersionUrl
    +80       */
    +81      public String getOldSchemaVersionUrl() {
    +82          return oldSchemaVersionUrl;
    +83      }
    +84  
    +85      /**
    +86       * Set the value of oldSchemaVersionUrl.
    +87       *
    +88       * @param oldSchemaVersionUrl new value of oldSchemaVersionUrl
    +89       */
    +90      public void setOldSchemaVersionUrl(String oldSchemaVersionUrl) {
    +91          this.oldSchemaVersionUrl = oldSchemaVersionUrl;
    +92      }
    +93      /**
    +94       * a timestamp - epoch time.
    +95       */
    +96      private long timestamp;
    +97  
    +98      /**
    +99       * Get the value of timestamp - epoch time.
    +100      *
    +101      * @return the value of timestamp - epoch time
    +102      */
    +103     public long getTimestamp() {
    +104         return timestamp;
    +105     }
    +106 
    +107     /**
    +108      * Set the value of timestamp - epoch time.
    +109      *
    +110      * @param timestamp new value of timestamp - epoch time
    +111      */
    +112     public void setTimestamp(long timestamp) {
    +113         this.timestamp = timestamp;
    +114     }
    +115     /**
    +116      * indicates whether or not this item should be updated.
    +117      */
    +118     private boolean needsUpdate = true;
    +119 
    +120     /**
    +121      * Get the value of needsUpdate.
    +122      *
    +123      * @return the value of needsUpdate
    +124      */
    +125     public boolean getNeedsUpdate() {
    +126         return needsUpdate;
    +127     }
    +128 
    +129     /**
    +130      * Set the value of needsUpdate.
    +131      *
    +132      * @param needsUpdate new value of needsUpdate
    +133      */
    +134     public void setNeedsUpdate(boolean needsUpdate) {
    +135         this.needsUpdate = needsUpdate;
    +136     }
    +137 }
    +
    +
    + + + diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/ProcessTask.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/ProcessTask.html new file mode 100644 index 000000000..4c4be4c31 --- /dev/null +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/ProcessTask.html @@ -0,0 +1,196 @@ + + + +ProcessTask 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.data.update.nvd;
    +19  
    +20  import java.io.File;
    +21  import java.io.FileNotFoundException;
    +22  import java.io.IOException;
    +23  import java.sql.SQLException;
    +24  import java.util.List;
    +25  import java.util.Map;
    +26  import java.util.concurrent.Callable;
    +27  import javax.xml.parsers.ParserConfigurationException;
    +28  import javax.xml.parsers.SAXParser;
    +29  import javax.xml.parsers.SAXParserFactory;
    +30  import org.owasp.dependencycheck.data.nvdcve.CveDB;
    +31  import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
    +32  import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties;
    +33  import org.owasp.dependencycheck.data.update.exception.UpdateException;
    +34  import org.owasp.dependencycheck.dependency.VulnerableSoftware;
    +35  import org.owasp.dependencycheck.utils.Settings;
    +36  import org.slf4j.Logger;
    +37  import org.slf4j.LoggerFactory;
    +38  import org.xml.sax.SAXException;
    +39  
    +40  /**
    +41   * A callable task that will process a given set of NVD CVE xml files and update the Cve Database accordingly.
    +42   *
    +43   * @author Jeremy Long
    +44   */
    +45  public class ProcessTask implements Callable<ProcessTask> {
    +46  
    +47      /**
    +48       * The logger.
    +49       */
    +50      private static final Logger LOGGER = LoggerFactory.getLogger(ProcessTask.class);
    +51      /**
    +52       * A field to store any update exceptions that occur during the "call".
    +53       */
    +54      private UpdateException exception = null;
    +55  
    +56      /**
    +57       * Get the value of exception.
    +58       *
    +59       * @return the value of exception
    +60       */
    +61      public UpdateException getException() {
    +62          return exception;
    +63      }
    +64  
    +65      /**
    +66       * Set the value of exception.
    +67       *
    +68       * @param exception new value of exception
    +69       */
    +70      public void setException(UpdateException exception) {
    +71          this.exception = exception;
    +72      }
    +73      /**
    +74       * A reference to the CveDB.
    +75       */
    +76      private final CveDB cveDB;
    +77      /**
    +78       * A reference to the callable download task.
    +79       */
    +80      private final DownloadTask filePair;
    +81      /**
    +82       * A reference to the properties.
    +83       */
    +84      private final DatabaseProperties properties;
    +85      /**
    +86       * A reference to the global settings object.
    +87       */
    +88      private Settings settings;
    +89  
    +90      /**
    +91       * Constructs a new ProcessTask used to process an NVD CVE update.
    +92       *
    +93       * @param cveDB the data store object
    +94       * @param filePair the download task that contains the URL references to download
    +95       * @param settings a reference to the global settings object; this is necessary so that when the thread is started the
    +96       * dependencies have a correct reference to the global settings.
    +97       */
    +98      public ProcessTask(final CveDB cveDB, final DownloadTask filePair, Settings settings) {
    +99          this.cveDB = cveDB;
    +100         this.filePair = filePair;
    +101         this.properties = cveDB.getDatabaseProperties();
    +102         this.settings = settings;
    +103     }
    +104 
    +105     /**
    +106      * Implements the callable interface.
    +107      *
    +108      * @return this object
    +109      * @throws Exception thrown if there is an exception; note that any UpdateExceptions are simply added to the tasks exception
    +110      * collection
    +111      */
    +112     @Override
    +113     public ProcessTask call() throws Exception {
    +114         try {
    +115             Settings.setInstance(settings);
    +116             processFiles();
    +117         } catch (UpdateException ex) {
    +118             this.exception = ex;
    +119         } finally {
    +120             Settings.cleanup(false);
    +121         }
    +122         return this;
    +123     }
    +124 
    +125     /**
    +126      * Imports the NVD CVE XML File into the Lucene Index.
    +127      *
    +128      * @param file the file containing the NVD CVE XML
    +129      * @param oldVersion contains the file containing the NVD CVE XML 1.2
    +130      * @throws ParserConfigurationException is thrown if there is a parser configuration exception
    +131      * @throws SAXException is thrown if there is a SAXException
    +132      * @throws IOException is thrown if there is a IO Exception
    +133      * @throws SQLException is thrown if there is a SQL exception
    +134      * @throws DatabaseException is thrown if there is a database exception
    +135      * @throws ClassNotFoundException thrown if the h2 database driver cannot be loaded
    +136      */
    +137     protected void importXML(File file, File oldVersion) throws ParserConfigurationException,
    +138             SAXException, IOException, SQLException, DatabaseException, ClassNotFoundException {
    +139 
    +140         final SAXParserFactory factory = SAXParserFactory.newInstance();
    +141         final SAXParser saxParser = factory.newSAXParser();
    +142 
    +143         final NvdCve12Handler cve12Handler = new NvdCve12Handler();
    +144         saxParser.parse(oldVersion, cve12Handler);
    +145         final Map<String, List<VulnerableSoftware>> prevVersionVulnMap = cve12Handler.getVulnerabilities();
    +146 
    +147         final NvdCve20Handler cve20Handler = new NvdCve20Handler();
    +148         cve20Handler.setCveDB(cveDB);
    +149         cve20Handler.setPrevVersionVulnMap(prevVersionVulnMap);
    +150         saxParser.parse(file, cve20Handler);
    +151     }
    +152 
    +153     /**
    +154      * Processes the NVD CVE XML file and imports the data into the DB.
    +155      *
    +156      * @throws UpdateException thrown if there is an error loading the data into the database
    +157      */
    +158     private void processFiles() throws UpdateException {
    +159         LOGGER.info("Processing Started for NVD CVE - {}", filePair.getNvdCveInfo().getId());
    +160         try {
    +161             importXML(filePair.getFirst(), filePair.getSecond());
    +162             cveDB.commit();
    +163             properties.save(filePair.getNvdCveInfo());
    +164         } catch (FileNotFoundException ex) {
    +165             throw new UpdateException(ex);
    +166         } catch (ParserConfigurationException ex) {
    +167             throw new UpdateException(ex);
    +168         } catch (SAXException ex) {
    +169             throw new UpdateException(ex);
    +170         } catch (IOException ex) {
    +171             throw new UpdateException(ex);
    +172         } catch (SQLException ex) {
    +173             throw new UpdateException(ex);
    +174         } catch (DatabaseException ex) {
    +175             throw new UpdateException(ex);
    +176         } catch (ClassNotFoundException ex) {
    +177             throw new UpdateException(ex);
    +178         } finally {
    +179             filePair.cleanup();
    +180         }
    +181         LOGGER.info("Processing Complete for NVD CVE - {}", filePair.getNvdCveInfo().getId());
    +182     }
    +183 }
    +
    +
    + + + diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/UpdateableNvdCve.html b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/UpdateableNvdCve.html new file mode 100644 index 000000000..68ab2a5fa --- /dev/null +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/UpdateableNvdCve.html @@ -0,0 +1,197 @@ + + + +UpdateableNvdCve 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) 2012 Jeremy Long. All Rights Reserved.
    +17   */
    +18  package org.owasp.dependencycheck.data.update.nvd;
    +19  
    +20  import java.net.MalformedURLException;
    +21  import java.net.URL;
    +22  import java.util.Iterator;
    +23  import java.util.Map;
    +24  import java.util.Map.Entry;
    +25  import java.util.TreeMap;
    +26  import org.owasp.dependencycheck.utils.DownloadFailedException;
    +27  import org.owasp.dependencycheck.utils.Downloader;
    +28  
    +29  /**
    +30   * Contains a collection of updateable NvdCveInfo objects. This is used to determine which files need to be downloaded and
    +31   * processed.
    +32   *
    +33   * @author Jeremy Long
    +34   */
    +35  public class UpdateableNvdCve implements java.lang.Iterable<NvdCveInfo>, Iterator<NvdCveInfo> {
    +36  
    +37      /**
    +38       * A collection of sources of data.
    +39       */
    +40      private Map<String, NvdCveInfo> collection = new TreeMap<String, NvdCveInfo>();
    +41  
    +42      /**
    +43       * Returns the collection of NvdCveInfo objects. This method is mainly used for testing.
    +44       *
    +45       * @return the collection of NvdCveInfo objects
    +46       */
    +47      protected Map<String, NvdCveInfo> getCollection() {
    +48          return collection;
    +49      }
    +50  
    +51      /**
    +52       * Gets whether or not an update is needed.
    +53       *
    +54       * @return true or false depending on whether an update is needed
    +55       */
    +56      public boolean isUpdateNeeded() {
    +57          for (NvdCveInfo item : this) {
    +58              if (item.getNeedsUpdate()) {
    +59                  return true;
    +60              }
    +61          }
    +62          return false;
    +63      }
    +64  
    +65      /**
    +66       * Adds a new entry of updateable information to the contained collection.
    +67       *
    +68       * @param id the key for the item to be added
    +69       * @param url the URL to download the item
    +70       * @param oldUrl the URL for the old version of the item (the NVD CVE old schema still contains useful data we need).
    +71       * @throws MalformedURLException thrown if the URL provided is invalid
    +72       * @throws DownloadFailedException thrown if the download fails.
    +73       */
    +74      public void add(String id, String url, String oldUrl) throws MalformedURLException, DownloadFailedException {
    +75          add(id, url, oldUrl, false);
    +76      }
    +77  
    +78      /**
    +79       * Adds a new entry of updateable information to the contained collection.
    +80       *
    +81       * @param id the key for the item to be added
    +82       * @param url the URL to download the item
    +83       * @param oldUrl the URL for the old version of the item (the NVD CVE old schema still contains useful data we need).
    +84       * @param needsUpdate whether or not the data needs to be updated
    +85       * @throws MalformedURLException thrown if the URL provided is invalid
    +86       * @throws DownloadFailedException thrown if the download fails.
    +87       */
    +88      public void add(String id, String url, String oldUrl, boolean needsUpdate) throws MalformedURLException, DownloadFailedException {
    +89          final NvdCveInfo item = new NvdCveInfo();
    +90          item.setNeedsUpdate(needsUpdate); //the others default to true, to make life easier later this should default to false.
    +91          item.setId(id);
    +92          item.setUrl(url);
    +93          item.setOldSchemaVersionUrl(oldUrl);
    +94          item.setTimestamp(Downloader.getLastModified(new URL(url)));
    +95          collection.put(id, item);
    +96      }
    +97  
    +98      /**
    +99       * Clears the contained collection of NvdCveInfo entries.
    +100      */
    +101     public void clear() {
    +102         collection.clear();
    +103     }
    +104 
    +105     /**
    +106      * Returns the timestamp for the given entry.
    +107      *
    +108      * @param key the key to lookup in the collection of NvdCveInfo items
    +109      * @return the timestamp for the given entry
    +110      */
    +111     public long getTimeStamp(String key) {
    +112         return collection.get(key).getTimestamp();
    +113     }
    +114     /**
    +115      * An internal iterator used to implement iterable.
    +116      */
    +117     private Iterator<Entry<String, NvdCveInfo>> iterableContent = null;
    +118 
    +119     /**
    +120      * <p>
    +121      * Returns an iterator for the NvdCveInfo contained.</p>
    +122      * <p>
    +123      * <b>This method is not thread safe.</b></p>
    +124      *
    +125      * @return an NvdCveInfo Iterator
    +126      */
    +127     @Override
    +128     public Iterator<NvdCveInfo> iterator() {
    +129         iterableContent = collection.entrySet().iterator();
    +130         return this;
    +131     }
    +132 
    +133     /**
    +134      * <p>
    +135      * Returns whether or not there is another item in the collection.</p>
    +136      * <p>
    +137      * <b>This method is not thread safe.</b></p>
    +138      *
    +139      * @return true or false depending on whether or not another item exists in the collection
    +140      */
    +141     @Override
    +142     public boolean hasNext() {
    +143         return iterableContent.hasNext();
    +144     }
    +145 
    +146     /**
    +147      * <p>
    +148      * Returns the next item in the collection.</p>
    +149      * <p>
    +150      * <b>This method is not thread safe.</b></p>
    +151      *
    +152      * @return the next NvdCveInfo item in the collection
    +153      */
    +154     @Override
    +155     public NvdCveInfo next() {
    +156         return iterableContent.next().getValue();
    +157     }
    +158 
    +159     /**
    +160      * <p>
    +161      * Removes the current NvdCveInfo object from the collection.</p>
    +162      * <p>
    +163      * <b>This method is not thread safe.</b></p>
    +164      */
    +165     @Override
    +166     public void remove() {
    +167         iterableContent.remove();
    +168     }
    +169 
    +170     /**
    +171      * Returns the specified item from the collection.
    +172      *
    +173      * @param key the key to lookup the return value
    +174      * @return the NvdCveInfo object stored using the specified key
    +175      */
    +176     public NvdCveInfo get(String key) {
    +177         return collection.get(key);
    +178     }
    +179 
    +180     @Override
    +181     public String toString() {
    +182         return "Updateable{" + "size=" + collection.size() + '}';
    +183     }
    +184 }
    +
    +
    + + + 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 new file mode 100644 index 000000000..4efcb997a --- /dev/null +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/package-frame.html @@ -0,0 +1,42 @@ + + + + + + Dependency-Check Core 1.3.0 Reference Package org.owasp.dependencycheck.data.update.nvd + + + + +

    + org.owasp.dependencycheck.data.update.nvd +

    + +

    Classes

    + + + + + \ No newline at end of file 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 new file mode 100644 index 000000000..7a5d2b903 --- /dev/null +++ b/dependency-check-core/xref/org/owasp/dependencycheck/data/update/nvd/package-summary.html @@ -0,0 +1,99 @@ + + + + + + Dependency-Check Core 1.3.0 Reference Package org.owasp.dependencycheck.data.update.nvd + + + +
    + +
    +
    + +
    + +

    Package org.owasp.dependencycheck.data.update.nvd

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Class Summary
    + DownloadTask +
    + Element +
    + NvdCve12Handler +
    + NvdCve20Handler +
    + NvdCveInfo +
    + ProcessTask +
    + UpdateableNvdCve +
    + +
    + +
    +
    + +
    +
    + + + \ No newline at end of file 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 866ae8136..73756d43c 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.2.11 Reference Package org.owasp.dependencycheck.data.update + Dependency-Check Core 1.3.0 Reference Package org.owasp.dependencycheck.data.update @@ -16,25 +16,22 @@ 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 a08bb5999..9069389ee 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.2.11 Reference Package org.owasp.dependencycheck.data.update + Dependency-Check Core 1.3.0 Reference Package org.owasp.dependencycheck.data.update @@ -36,39 +36,34 @@
    + BaseUpdater +
    CachedWebDataSource
    + CpeUpdater +
    EngineVersionCheck
    - NvdCveInfo -
    NvdCveUpdater
    - StandardUpdate -
    UpdateService
    - UpdateableNvdCve -
    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 60187fd13..a6e8dc02d 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/dependency/Dependency.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/dependency/Dependency.html @@ -35,793 +35,731 @@ 27 import java.util.Set; 28 import java.util.SortedSet; 29 import java.util.TreeSet; -30 import java.util.logging.Level; -31 import java.util.logging.Logger; +30 +31 import org.apache.commons.lang.ObjectUtils; 32 import org.owasp.dependencycheck.data.nexus.MavenArtifact; 33 import org.owasp.dependencycheck.utils.Checksum; -34 import org.owasp.dependencycheck.utils.FileUtils; -35 -36 /** -37 * A program dependency. This object is one of the core components within DependencyCheck. It is used to collect information about -38 * the dependency in the form of evidence. The Evidence is then used to determine if there are any known, published, -39 * vulnerabilities associated with the program dependency. -40 * -41 * @author Jeremy Long -42 */ -43 public class Dependency implements Serializable, Comparable<Dependency> { -44 -45 /** -46 * The logger. -47 */ -48 private static final Logger LOGGER = Logger.getLogger(Dependency.class.getName()); -49 /** -50 * The actual file path of the dependency on disk. -51 */ -52 private String actualFilePath; -53 /** -54 * The file path to display. -55 */ -56 private String filePath; -57 /** -58 * The file name of the dependency. -59 */ -60 private String fileName; -61 /** -62 * The file extension of the dependency. -63 */ -64 private String fileExtension; -65 /** -66 * The md5 hash of the dependency. -67 */ -68 private String md5sum; -69 /** -70 * The SHA1 hash of the dependency. -71 */ -72 private String sha1sum; -73 /** -74 * A list of Identifiers. -75 */ -76 private Set<Identifier> identifiers; -77 /** -78 * A collection of vendor evidence. -79 */ -80 private final EvidenceCollection vendorEvidence; -81 /** -82 * A collection of product evidence. -83 */ -84 private final EvidenceCollection productEvidence; -85 /** -86 * A collection of version evidence. -87 */ -88 private final EvidenceCollection versionEvidence; -89 +34 import org.slf4j.Logger; +35 import org.slf4j.LoggerFactory; +36 +37 /** +38 * A program dependency. This object is one of the core components within DependencyCheck. It is used to collect information about +39 * the dependency in the form of evidence. The Evidence is then used to determine if there are any known, published, +40 * vulnerabilities associated with the program dependency. +41 * +42 * @author Jeremy Long +43 */ +44 public class Dependency implements Serializable, Comparable<Dependency> { +45 +46 /** +47 * The logger. +48 */ +49 private static final Logger LOGGER = LoggerFactory.getLogger(Dependency.class); +50 /** +51 * Used as starting point for generating the value in {@link #hashCode()}. +52 */ +53 private static final int MAGIC_HASH_INIT_VALUE = 3; +54 /** +55 * Used as a multiplier for generating the value in {@link #hashCode()}. +56 */ +57 private static final int MAGIC_HASH_MULTIPLIER = 47; +58 /** +59 * The actual file path of the dependency on disk. +60 */ +61 private String actualFilePath; +62 /** +63 * The file path to display. +64 */ +65 private String filePath; +66 /** +67 * The file name of the dependency. +68 */ +69 private String fileName; +70 /** +71 * The md5 hash of the dependency. +72 */ +73 private String md5sum; +74 /** +75 * The SHA1 hash of the dependency. +76 */ +77 private String sha1sum; +78 /** +79 * A list of Identifiers. +80 */ +81 private Set<Identifier> identifiers; +82 /** +83 * A collection of vendor evidence. +84 */ +85 private final EvidenceCollection vendorEvidence; +86 /** +87 * A collection of product evidence. +88 */ +89 private final EvidenceCollection productEvidence; 90 /** -91 * Constructs a new Dependency object. +91 * A collection of version evidence. 92 */ -93 public Dependency() { -94 vendorEvidence = new EvidenceCollection(); -95 productEvidence = new EvidenceCollection(); -96 versionEvidence = new EvidenceCollection(); -97 identifiers = new TreeSet<Identifier>(); -98 vulnerabilities = new TreeSet<Vulnerability>(new VulnerabilityComparator()); -99 suppressedIdentifiers = new TreeSet<Identifier>(); -100 suppressedVulnerabilities = new TreeSet<Vulnerability>(new VulnerabilityComparator()); -101 } -102 -103 /** -104 * Constructs a new Dependency object. -105 * -106 * @param file the File to create the dependency object from. -107 */ -108 public Dependency(File file) { -109 this(); -110 this.actualFilePath = file.getPath(); -111 this.filePath = this.actualFilePath; -112 this.fileName = file.getName(); -113 this.fileExtension = FileUtils.getFileExtension(fileName); -114 determineHashes(file); -115 } -116 -117 /** -118 * Returns the file name of the dependency. -119 * -120 * @return the file name of the dependency -121 */ -122 public String getFileName() { -123 return this.fileName; -124 } -125 -126 /** -127 * Returns the file name of the dependency with the backslash escaped for use in JavaScript. This is a complete hack as I -128 * could not get the replace to work in the template itself. -129 * -130 * @return the file name of the dependency with the backslash escaped for use in JavaScript -131 */ -132 public String getFileNameForJavaScript() { -133 return this.fileName.replace("\\", "\\\\"); -134 } -135 -136 /** -137 * Sets the file name of the dependency. -138 * -139 * @param fileName the file name of the dependency -140 */ -141 public void setFileName(String fileName) { -142 this.fileName = fileName; -143 } -144 -145 /** -146 * Sets the actual file path of the dependency on disk. -147 * -148 * @param actualFilePath the file path of the dependency -149 */ -150 public void setActualFilePath(String actualFilePath) { -151 this.actualFilePath = actualFilePath; -152 if (this.sha1sum == null) { -153 final File file = new File(this.actualFilePath); -154 determineHashes(file); -155 } -156 } -157 -158 /** -159 * Gets the file path of the dependency. -160 * -161 * @return the file path of the dependency -162 */ -163 public String getActualFilePath() { -164 return this.actualFilePath; -165 } -166 -167 /** -168 * Gets a reference to the File object. -169 * -170 * @return the File object -171 */ -172 public File getActualFile() { -173 return new File(this.actualFilePath); -174 } -175 -176 /** -177 * Sets the file path of the dependency. -178 * -179 * @param filePath the file path of the dependency -180 */ -181 public void setFilePath(String filePath) { -182 this.filePath = filePath; -183 } -184 -185 /** -186 * The file name to display in reports. -187 */ -188 private String displayName = null; -189 -190 /** -191 * Sets the file name to display in reports. -192 * -193 * @param displayName the name to display -194 */ -195 public void setDisplayFileName(String displayName) { -196 this.displayName = displayName; -197 } -198 -199 /** -200 * Returns the file name to display in reports; if no display file name has been set it will default to the actual file name. -201 * -202 * @return the file name to display -203 */ -204 public String getDisplayFileName() { -205 if (displayName == null) { -206 return this.fileName; -207 } -208 return this.displayName; -209 } -210 -211 /** -212 * <p> -213 * Gets the file path of the dependency.</p> -214 * <p> -215 * <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 -216 * the getActualFilePath().</p> -217 * -218 * @return the file path of the dependency -219 */ -220 public String getFilePath() { -221 return this.filePath; -222 } -223 -224 /** -225 * Sets the file extension of the dependency. -226 * -227 * @param fileExtension the file name of the dependency -228 */ -229 public void setFileExtension(String fileExtension) { -230 this.fileExtension = fileExtension; -231 } -232 -233 /** -234 * Gets the file extension of the dependency. -235 * -236 * @return the file extension of the dependency -237 */ -238 public String getFileExtension() { -239 return this.fileExtension; -240 } -241 -242 /** -243 * Returns the MD5 Checksum of the dependency file. -244 * -245 * @return the MD5 Checksum -246 */ -247 public String getMd5sum() { -248 return this.md5sum; -249 } -250 -251 /** -252 * Sets the MD5 Checksum of the dependency. -253 * -254 * @param md5sum the MD5 Checksum -255 */ -256 public void setMd5sum(String md5sum) { -257 this.md5sum = md5sum; -258 } -259 -260 /** -261 * Returns the SHA1 Checksum of the dependency. -262 * -263 * @return the SHA1 Checksum -264 */ -265 public String getSha1sum() { -266 return this.sha1sum; -267 } -268 -269 /** -270 * Sets the SHA1 Checksum of the dependency. -271 * -272 * @param sha1sum the SHA1 Checksum -273 */ -274 public void setSha1sum(String sha1sum) { -275 this.sha1sum = sha1sum; -276 } -277 -278 /** -279 * Returns a List of Identifiers. -280 * -281 * @return an ArrayList of Identifiers -282 */ -283 public Set<Identifier> getIdentifiers() { -284 return this.identifiers; -285 } -286 -287 /** -288 * Sets a List of Identifiers. -289 * -290 * @param identifiers A list of Identifiers -291 */ -292 public void setIdentifiers(Set<Identifier> identifiers) { -293 this.identifiers = identifiers; -294 } -295 -296 /** -297 * Adds an entry to the list of detected Identifiers for the dependency file. -298 * -299 * @param type the type of identifier (such as CPE) -300 * @param value the value of the identifier -301 * @param url the URL of the identifier -302 */ -303 public void addIdentifier(String type, String value, String url) { -304 final Identifier i = new Identifier(type, value, url); +93 private final EvidenceCollection versionEvidence; +94 +95 /** +96 * Constructs a new Dependency object. +97 */ +98 public Dependency() { +99 vendorEvidence = new EvidenceCollection(); +100 productEvidence = new EvidenceCollection(); +101 versionEvidence = new EvidenceCollection(); +102 identifiers = new TreeSet<Identifier>(); +103 vulnerabilities = new TreeSet<Vulnerability>(new VulnerabilityComparator()); +104 suppressedIdentifiers = new TreeSet<Identifier>(); +105 suppressedVulnerabilities = new TreeSet<Vulnerability>(new VulnerabilityComparator()); +106 } +107 +108 /** +109 * Constructs a new Dependency object. +110 * +111 * @param file the File to create the dependency object from. +112 */ +113 public Dependency(File file) { +114 this(); +115 this.actualFilePath = file.getAbsolutePath(); +116 this.filePath = this.actualFilePath; +117 this.fileName = file.getName(); +118 determineHashes(file); +119 } +120 +121 /** +122 * Returns the file name of the dependency. +123 * +124 * @return the file name of the dependency +125 */ +126 public String getFileName() { +127 return this.fileName; +128 } +129 +130 /** +131 * Returns the file name of the dependency with the backslash escaped for use in JavaScript. This is a complete hack as I +132 * could not get the replace to work in the template itself. +133 * +134 * @return the file name of the dependency with the backslash escaped for use in JavaScript +135 */ +136 public String getFileNameForJavaScript() { +137 return this.fileName.replace("\\", "\\\\"); +138 } +139 +140 /** +141 * Sets the file name of the dependency. +142 * +143 * @param fileName the file name of the dependency +144 */ +145 public void setFileName(String fileName) { +146 this.fileName = fileName; +147 } +148 +149 /** +150 * Sets the actual file path of the dependency on disk. +151 * +152 * @param actualFilePath the file path of the dependency +153 */ +154 public void setActualFilePath(String actualFilePath) { +155 this.actualFilePath = actualFilePath; +156 if (this.sha1sum == null) { +157 final File file = new File(this.actualFilePath); +158 determineHashes(file); +159 } +160 } +161 +162 /** +163 * Gets the file path of the dependency. +164 * +165 * @return the file path of the dependency +166 */ +167 public String getActualFilePath() { +168 return this.actualFilePath; +169 } +170 +171 /** +172 * Gets a reference to the File object. +173 * +174 * @return the File object +175 */ +176 public File getActualFile() { +177 return new File(this.actualFilePath); +178 } +179 +180 /** +181 * Sets the file path of the dependency. +182 * +183 * @param filePath the file path of the dependency +184 */ +185 public void setFilePath(String filePath) { +186 this.filePath = filePath; +187 } +188 +189 /** +190 * The file name to display in reports. +191 */ +192 private String displayName = null; +193 +194 /** +195 * Sets the file name to display in reports. +196 * +197 * @param displayName the name to display +198 */ +199 public void setDisplayFileName(String displayName) { +200 this.displayName = displayName; +201 } +202 +203 /** +204 * Returns the file name to display in reports; if no display file name has been set it will default to the actual file name. +205 * +206 * @return the file name to display +207 */ +208 public String getDisplayFileName() { +209 if (displayName == null) { +210 return this.fileName; +211 } +212 return this.displayName; +213 } +214 +215 /** +216 * <p> +217 * Gets the file path of the dependency.</p> +218 * <p> +219 * <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 +220 * the getActualFilePath().</p> +221 * +222 * @return the file path of the dependency +223 */ +224 public String getFilePath() { +225 return this.filePath; +226 } +227 +228 /** +229 * Returns the MD5 Checksum of the dependency file. +230 * +231 * @return the MD5 Checksum +232 */ +233 public String getMd5sum() { +234 return this.md5sum; +235 } +236 +237 /** +238 * Sets the MD5 Checksum of the dependency. +239 * +240 * @param md5sum the MD5 Checksum +241 */ +242 public void setMd5sum(String md5sum) { +243 this.md5sum = md5sum; +244 } +245 +246 /** +247 * Returns the SHA1 Checksum of the dependency. +248 * +249 * @return the SHA1 Checksum +250 */ +251 public String getSha1sum() { +252 return this.sha1sum; +253 } +254 +255 /** +256 * Sets the SHA1 Checksum of the dependency. +257 * +258 * @param sha1sum the SHA1 Checksum +259 */ +260 public void setSha1sum(String sha1sum) { +261 this.sha1sum = sha1sum; +262 } +263 +264 /** +265 * Returns a List of Identifiers. +266 * +267 * @return an ArrayList of Identifiers +268 */ +269 public Set<Identifier> getIdentifiers() { +270 return this.identifiers; +271 } +272 +273 /** +274 * Sets a List of Identifiers. +275 * +276 * @param identifiers A list of Identifiers +277 */ +278 public void setIdentifiers(Set<Identifier> identifiers) { +279 this.identifiers = identifiers; +280 } +281 +282 /** +283 * Adds an entry to the list of detected Identifiers for the dependency file. +284 * +285 * @param type the type of identifier (such as CPE) +286 * @param value the value of the identifier +287 * @param url the URL of the identifier +288 */ +289 public void addIdentifier(String type, String value, String url) { +290 final Identifier i = new Identifier(type, value, url); +291 this.identifiers.add(i); +292 } +293 +294 /** +295 * Adds an entry to the list of detected Identifiers for the dependency file. +296 * +297 * @param type the type of identifier (such as CPE) +298 * @param value the value of the identifier +299 * @param url the URL of the identifier +300 * @param confidence the confidence in the Identifier being accurate +301 */ +302 public void addIdentifier(String type, String value, String url, Confidence confidence) { +303 final Identifier i = new Identifier(type, value, url); +304 i.setConfidence(confidence); 305 this.identifiers.add(i); 306 } 307 308 /** -309 * Adds an entry to the list of detected Identifiers for the dependency file. +309 * Adds the maven artifact as evidence. 310 * -311 * @param type the type of identifier (such as CPE) -312 * @param value the value of the identifier -313 * @param url the URL of the identifier -314 * @param confidence the confidence in the Identifier being accurate -315 */ -316 public void addIdentifier(String type, String value, String url, Confidence confidence) { -317 final Identifier i = new Identifier(type, value, url); -318 i.setConfidence(confidence); -319 this.identifiers.add(i); -320 } -321 -322 /** -323 * Adds the maven artifact as evidence. -324 * -325 * @param source The source of the evidence -326 * @param mavenArtifact The maven artifact -327 * @param confidence The confidence level of this evidence -328 */ -329 public void addAsEvidence(String source, MavenArtifact mavenArtifact, Confidence confidence) { -330 if (mavenArtifact.getGroupId() != null && !mavenArtifact.getGroupId().isEmpty()) { -331 this.getVendorEvidence().addEvidence(source, "groupid", mavenArtifact.getGroupId(), confidence); -332 } -333 if (mavenArtifact.getArtifactId() != null && !mavenArtifact.getArtifactId().isEmpty()) { -334 this.getProductEvidence().addEvidence(source, "artifactid", mavenArtifact.getArtifactId(), confidence); -335 } -336 if (mavenArtifact.getVersion() != null && !mavenArtifact.getVersion().isEmpty()) { -337 this.getVersionEvidence().addEvidence(source, "version", mavenArtifact.getVersion(), confidence); -338 } -339 if (mavenArtifact.getArtifactUrl() != null && !mavenArtifact.getArtifactUrl().isEmpty()) { -340 boolean found = false; -341 for (Identifier i : this.getIdentifiers()) { -342 if ("maven".equals(i.getType()) && i.getValue().equals(mavenArtifact.toString())) { -343 found = true; -344 i.setConfidence(Confidence.HIGHEST); -345 final String url = "http://search.maven.org/#search|ga|1|1%3A%22" + this.getSha1sum() + "%22"; -346 i.setUrl(url); -347 //i.setUrl(mavenArtifact.getArtifactUrl()); -348 LOGGER.fine(String.format("Already found identifier %s. Confidence set to highest", i.getValue())); -349 break; -350 } -351 } -352 if (!found) { -353 LOGGER.fine(String.format("Adding new maven identifier %s", mavenArtifact.toString())); -354 this.addIdentifier("maven", mavenArtifact.toString(), mavenArtifact.getArtifactUrl(), Confidence.HIGHEST); -355 } -356 } -357 } +311 * @param source The source of the evidence +312 * @param mavenArtifact The maven artifact +313 * @param confidence The confidence level of this evidence +314 */ +315 public void addAsEvidence(String source, MavenArtifact mavenArtifact, Confidence confidence) { +316 if (mavenArtifact.getGroupId() != null && !mavenArtifact.getGroupId().isEmpty()) { +317 this.getVendorEvidence().addEvidence(source, "groupid", mavenArtifact.getGroupId(), confidence); +318 } +319 if (mavenArtifact.getArtifactId() != null && !mavenArtifact.getArtifactId().isEmpty()) { +320 this.getProductEvidence().addEvidence(source, "artifactid", mavenArtifact.getArtifactId(), confidence); +321 } +322 if (mavenArtifact.getVersion() != null && !mavenArtifact.getVersion().isEmpty()) { +323 this.getVersionEvidence().addEvidence(source, "version", mavenArtifact.getVersion(), confidence); +324 } +325 if (mavenArtifact.getArtifactUrl() != null && !mavenArtifact.getArtifactUrl().isEmpty()) { +326 boolean found = false; +327 for (Identifier i : this.getIdentifiers()) { +328 if ("maven".equals(i.getType()) && i.getValue().equals(mavenArtifact.toString())) { +329 found = true; +330 i.setConfidence(Confidence.HIGHEST); +331 final String url = "http://search.maven.org/#search|ga|1|1%3A%22" + this.getSha1sum() + "%22"; +332 i.setUrl(url); +333 //i.setUrl(mavenArtifact.getArtifactUrl()); +334 LOGGER.debug("Already found identifier {}. Confidence set to highest", i.getValue()); +335 break; +336 } +337 } +338 if (!found) { +339 LOGGER.debug("Adding new maven identifier {}", mavenArtifact.toString()); +340 this.addIdentifier("maven", mavenArtifact.toString(), mavenArtifact.getArtifactUrl(), Confidence.HIGHEST); +341 } +342 } +343 } +344 +345 /** +346 * Adds an entry to the list of detected Identifiers for the dependency file. +347 * +348 * @param identifier the identifier to add +349 */ +350 public void addIdentifier(Identifier identifier) { +351 this.identifiers.add(identifier); +352 } +353 +354 /** +355 * A set of identifiers that have been suppressed. +356 */ +357 private Set<Identifier> suppressedIdentifiers; 358 359 /** -360 * Adds an entry to the list of detected Identifiers for the dependency file. +360 * Get the value of suppressedIdentifiers. 361 * -362 * @param identifier the identifier to add +362 * @return the value of suppressedIdentifiers 363 */ -364 public void addIdentifier(Identifier identifier) { -365 this.identifiers.add(identifier); +364 public Set<Identifier> getSuppressedIdentifiers() { +365 return suppressedIdentifiers; 366 } 367 368 /** -369 * A set of identifiers that have been suppressed. -370 */ -371 private Set<Identifier> suppressedIdentifiers; -372 -373 /** -374 * Get the value of suppressedIdentifiers. -375 * -376 * @return the value of suppressedIdentifiers -377 */ -378 public Set<Identifier> getSuppressedIdentifiers() { -379 return suppressedIdentifiers; -380 } -381 -382 /** -383 * Set the value of suppressedIdentifiers. -384 * -385 * @param suppressedIdentifiers new value of suppressedIdentifiers -386 */ -387 public void setSuppressedIdentifiers(Set<Identifier> suppressedIdentifiers) { -388 this.suppressedIdentifiers = suppressedIdentifiers; -389 } +369 * Set the value of suppressedIdentifiers. +370 * +371 * @param suppressedIdentifiers new value of suppressedIdentifiers +372 */ +373 public void setSuppressedIdentifiers(Set<Identifier> suppressedIdentifiers) { +374 this.suppressedIdentifiers = suppressedIdentifiers; +375 } +376 +377 /** +378 * Adds an identifier to the list of suppressed identifiers. +379 * +380 * @param identifier an identifier that was suppressed. +381 */ +382 public void addSuppressedIdentifier(Identifier identifier) { +383 this.suppressedIdentifiers.add(identifier); +384 } +385 +386 /** +387 * A set of vulnerabilities that have been suppressed. +388 */ +389 private SortedSet<Vulnerability> suppressedVulnerabilities; 390 391 /** -392 * Adds an identifier to the list of suppressed identifiers. +392 * Get the value of suppressedVulnerabilities. 393 * -394 * @param identifier an identifier that was suppressed. +394 * @return the value of suppressedVulnerabilities 395 */ -396 public void addSuppressedIdentifier(Identifier identifier) { -397 this.suppressedIdentifiers.add(identifier); +396 public SortedSet<Vulnerability> getSuppressedVulnerabilities() { +397 return suppressedVulnerabilities; 398 } 399 400 /** -401 * A set of vulnerabilities that have been suppressed. -402 */ -403 private SortedSet<Vulnerability> suppressedVulnerabilities; -404 -405 /** -406 * Get the value of suppressedVulnerabilities. -407 * -408 * @return the value of suppressedVulnerabilities -409 */ -410 public SortedSet<Vulnerability> getSuppressedVulnerabilities() { -411 return suppressedVulnerabilities; -412 } -413 -414 /** -415 * Set the value of suppressedVulnerabilities. -416 * -417 * @param suppressedVulnerabilities new value of suppressedVulnerabilities -418 */ -419 public void setSuppressedVulnerabilities(SortedSet<Vulnerability> suppressedVulnerabilities) { -420 this.suppressedVulnerabilities = suppressedVulnerabilities; -421 } -422 -423 /** -424 * Adds a vulnerability to the set of suppressed vulnerabilities. -425 * -426 * @param vulnerability the vulnerability that was suppressed -427 */ -428 public void addSuppressedVulnerability(Vulnerability vulnerability) { -429 this.suppressedVulnerabilities.add(vulnerability); -430 } -431 -432 /** -433 * Returns the evidence used to identify this dependency. -434 * -435 * @return an EvidenceCollection. -436 */ -437 public EvidenceCollection getEvidence() { -438 return EvidenceCollection.merge(this.productEvidence, this.vendorEvidence, this.versionEvidence); -439 } -440 -441 /** -442 * Returns the evidence used to identify this dependency. -443 * -444 * @return an EvidenceCollection. -445 */ -446 public Set<Evidence> getEvidenceForDisplay() { -447 return EvidenceCollection.mergeForDisplay(this.productEvidence, this.vendorEvidence, this.versionEvidence); -448 } -449 -450 /** -451 * Returns the evidence used to identify this dependency. -452 * -453 * @return an EvidenceCollection. -454 */ -455 public EvidenceCollection getEvidenceUsed() { -456 return EvidenceCollection.mergeUsed(this.productEvidence, this.vendorEvidence, this.versionEvidence); -457 } -458 -459 /** -460 * Gets the Vendor Evidence. -461 * -462 * @return an EvidenceCollection. -463 */ -464 public EvidenceCollection getVendorEvidence() { -465 return this.vendorEvidence; -466 } -467 -468 /** -469 * Gets the Product Evidence. -470 * -471 * @return an EvidenceCollection. -472 */ -473 public EvidenceCollection getProductEvidence() { -474 return this.productEvidence; -475 } +401 * Set the value of suppressedVulnerabilities. +402 * +403 * @param suppressedVulnerabilities new value of suppressedVulnerabilities +404 */ +405 public void setSuppressedVulnerabilities(SortedSet<Vulnerability> suppressedVulnerabilities) { +406 this.suppressedVulnerabilities = suppressedVulnerabilities; +407 } +408 +409 /** +410 * Adds a vulnerability to the set of suppressed vulnerabilities. +411 * +412 * @param vulnerability the vulnerability that was suppressed +413 */ +414 public void addSuppressedVulnerability(Vulnerability vulnerability) { +415 this.suppressedVulnerabilities.add(vulnerability); +416 } +417 +418 /** +419 * Returns the evidence used to identify this dependency. +420 * +421 * @return an EvidenceCollection. +422 */ +423 public EvidenceCollection getEvidence() { +424 return EvidenceCollection.merge(this.productEvidence, this.vendorEvidence, this.versionEvidence); +425 } +426 +427 /** +428 * Returns the evidence used to identify this dependency. +429 * +430 * @return an EvidenceCollection. +431 */ +432 public Set<Evidence> getEvidenceForDisplay() { +433 return EvidenceCollection.mergeForDisplay(this.productEvidence, this.vendorEvidence, this.versionEvidence); +434 } +435 +436 /** +437 * Returns the evidence used to identify this dependency. +438 * +439 * @return an EvidenceCollection. +440 */ +441 public EvidenceCollection getEvidenceUsed() { +442 return EvidenceCollection.mergeUsed(this.productEvidence, this.vendorEvidence, this.versionEvidence); +443 } +444 +445 /** +446 * Gets the Vendor Evidence. +447 * +448 * @return an EvidenceCollection. +449 */ +450 public EvidenceCollection getVendorEvidence() { +451 return this.vendorEvidence; +452 } +453 +454 /** +455 * Gets the Product Evidence. +456 * +457 * @return an EvidenceCollection. +458 */ +459 public EvidenceCollection getProductEvidence() { +460 return this.productEvidence; +461 } +462 +463 /** +464 * Gets the Version Evidence. +465 * +466 * @return an EvidenceCollection. +467 */ +468 public EvidenceCollection getVersionEvidence() { +469 return this.versionEvidence; +470 } +471 +472 /** +473 * The description of the JAR file. +474 */ +475 private String description; 476 477 /** -478 * Gets the Version Evidence. +478 * Get the value of description. 479 * -480 * @return an EvidenceCollection. +480 * @return the value of description 481 */ -482 public EvidenceCollection getVersionEvidence() { -483 return this.versionEvidence; +482 public String getDescription() { +483 return description; 484 } 485 486 /** -487 * The description of the JAR file. -488 */ -489 private String description; -490 -491 /** -492 * Get the value of description. -493 * -494 * @return the value of description -495 */ -496 public String getDescription() { -497 return description; -498 } +487 * Set the value of description. +488 * +489 * @param description new value of description +490 */ +491 public void setDescription(String description) { +492 this.description = description; +493 } +494 +495 /** +496 * The license that this dependency uses. +497 */ +498 private String license; 499 500 /** -501 * Set the value of description. +501 * Get the value of license. 502 * -503 * @param description new value of description +503 * @return the value of license 504 */ -505 public void setDescription(String description) { -506 this.description = description; +505 public String getLicense() { +506 return license; 507 } 508 509 /** -510 * The license that this dependency uses. -511 */ -512 private String license; -513 -514 /** -515 * Get the value of license. -516 * -517 * @return the value of license -518 */ -519 public String getLicense() { -520 return license; -521 } +510 * Set the value of license. +511 * +512 * @param license new value of license +513 */ +514 public void setLicense(String license) { +515 this.license = license; +516 } +517 +518 /** +519 * A list of vulnerabilities for this dependency. +520 */ +521 private SortedSet<Vulnerability> vulnerabilities; 522 523 /** -524 * Set the value of license. +524 * Get the list of vulnerabilities. 525 * -526 * @param license new value of license +526 * @return the list of vulnerabilities 527 */ -528 public void setLicense(String license) { -529 this.license = license; +528 public SortedSet<Vulnerability> getVulnerabilities() { +529 return vulnerabilities; 530 } 531 532 /** -533 * A list of vulnerabilities for this dependency. -534 */ -535 private SortedSet<Vulnerability> vulnerabilities; -536 -537 /** -538 * Get the list of vulnerabilities. -539 * -540 * @return the list of vulnerabilities -541 */ -542 public SortedSet<Vulnerability> getVulnerabilities() { -543 return vulnerabilities; -544 } -545 -546 /** -547 * Set the value of vulnerabilities. -548 * -549 * @param vulnerabilities new value of vulnerabilities -550 */ -551 public void setVulnerabilities(SortedSet<Vulnerability> vulnerabilities) { -552 this.vulnerabilities = vulnerabilities; -553 } -554 -555 /** -556 * Determines the sha1 and md5 sum for the given file. -557 * -558 * @param file the file to create checksums for -559 */ -560 private void determineHashes(File file) { -561 String md5 = null; -562 String sha1 = null; -563 try { -564 md5 = Checksum.getMD5Checksum(file); -565 sha1 = Checksum.getSHA1Checksum(file); -566 } catch (IOException ex) { -567 final String msg = String.format("Unable to read '%s' to determine hashes.", file.getName()); -568 LOGGER.log(Level.WARNING, msg); -569 LOGGER.log(Level.FINE, null, ex); -570 } catch (NoSuchAlgorithmException ex) { -571 final String msg = "Unable to use MD5 of SHA1 checksums."; -572 LOGGER.log(Level.WARNING, msg); -573 LOGGER.log(Level.FINE, null, ex); -574 } -575 this.setMd5sum(md5); -576 this.setSha1sum(sha1); -577 } -578 -579 /** -580 * Adds a vulnerability to the dependency. -581 * -582 * @param vulnerability a vulnerability outlining a vulnerability. -583 */ -584 public void addVulnerability(Vulnerability vulnerability) { -585 this.vulnerabilities.add(vulnerability); -586 } -587 -588 /** -589 * A collection of related dependencies. -590 */ -591 private Set<Dependency> relatedDependencies = new TreeSet<Dependency>(); -592 -593 /** -594 * Get the value of relatedDependencies. -595 * -596 * @return the value of relatedDependencies -597 */ -598 public Set<Dependency> getRelatedDependencies() { -599 return relatedDependencies; -600 } -601 -602 /** -603 * A list of projects that reference this dependency. -604 */ -605 private Set<String> projectReferences = new HashSet<String>(); -606 -607 /** -608 * Get the value of projectReferences. -609 * -610 * @return the value of projectReferences -611 */ -612 public Set<String> getProjectReferences() { -613 return projectReferences; -614 } -615 -616 /** -617 * Set the value of projectReferences. -618 * -619 * @param projectReferences new value of projectReferences -620 */ -621 public void setProjectReferences(Set<String> projectReferences) { -622 this.projectReferences = projectReferences; -623 } -624 -625 /** -626 * Adds a project reference. -627 * -628 * @param projectReference a project reference -629 */ -630 public void addProjectReference(String projectReference) { -631 this.projectReferences.add(projectReference); -632 } -633 -634 /** -635 * Add a collection of project reference. -636 * -637 * @param projectReferences a set of project references -638 */ -639 public void addAllProjectReferences(Set<String> projectReferences) { -640 this.projectReferences.addAll(projectReferences); -641 } -642 -643 /** -644 * Set the value of relatedDependencies. -645 * -646 * @param relatedDependencies new value of relatedDependencies -647 */ -648 public void setRelatedDependencies(Set<Dependency> relatedDependencies) { -649 this.relatedDependencies = relatedDependencies; -650 } -651 -652 /** -653 * Adds a related dependency. -654 * -655 * @param dependency a reference to the related dependency -656 */ -657 public void addRelatedDependency(Dependency dependency) { -658 if (this == dependency) { -659 LOGGER.warning("Attempted to add a circular reference - please post the log file to issue #172 here " -660 + "https://github.com/jeremylong/DependencyCheck/issues/172 "); -661 LOGGER.log(Level.FINE, "this: {0}", this.toString()); -662 LOGGER.log(Level.FINE, "dependency: {0}", dependency.toString()); -663 } else { -664 relatedDependencies.add(dependency); -665 } -666 } -667 -668 /** -669 * A list of available versions. -670 */ -671 private List<String> availableVersions = new ArrayList<String>(); -672 -673 /** -674 * Get the value of availableVersions. -675 * -676 * @return the value of availableVersions -677 */ -678 public List<String> getAvailableVersions() { -679 return availableVersions; -680 } -681 -682 /** -683 * Set the value of availableVersions. -684 * -685 * @param availableVersions new value of availableVersions -686 */ -687 public void setAvailableVersions(List<String> availableVersions) { -688 this.availableVersions = availableVersions; -689 } -690 -691 /** -692 * Adds a version to the available version list. -693 * -694 * @param version the version to add to the list -695 */ -696 public void addAvailableVersion(String version) { -697 this.availableVersions.add(version); -698 } -699 -700 /** -701 * Implementation of the Comparable<Dependency> interface. The comparison is solely based on the file name. -702 * -703 * @param o a dependency to compare -704 * @return an integer representing the natural ordering -705 */ -706 public int compareTo(Dependency o) { -707 return this.getFilePath().compareToIgnoreCase(o.getFilePath()); -708 } -709 -710 /** -711 * Implementation of the equals method. -712 * -713 * @param obj the object to compare -714 * @return true if the objects are equal, otherwise false -715 */ -716 @Override -717 public boolean equals(Object obj) { -718 if (obj == null) { -719 return false; -720 } -721 if (getClass() != obj.getClass()) { -722 return false; -723 } -724 final Dependency other = (Dependency) obj; -725 if ((this.actualFilePath == null) ? (other.actualFilePath != null) : !this.actualFilePath.equals(other.actualFilePath)) { -726 return false; -727 } -728 if ((this.filePath == null) ? (other.filePath != null) : !this.filePath.equals(other.filePath)) { -729 return false; -730 } -731 if ((this.fileName == null) ? (other.fileName != null) : !this.fileName.equals(other.fileName)) { -732 return false; -733 } -734 if ((this.fileExtension == null) ? (other.fileExtension != null) : !this.fileExtension.equals(other.fileExtension)) { -735 return false; -736 } -737 if ((this.md5sum == null) ? (other.md5sum != null) : !this.md5sum.equals(other.md5sum)) { -738 return false; -739 } -740 if ((this.sha1sum == null) ? (other.sha1sum != null) : !this.sha1sum.equals(other.sha1sum)) { -741 return false; -742 } -743 if (this.identifiers != other.identifiers && (this.identifiers == null || !this.identifiers.equals(other.identifiers))) { -744 return false; -745 } -746 if (this.vendorEvidence != other.vendorEvidence && (this.vendorEvidence == null || !this.vendorEvidence.equals(other.vendorEvidence))) { -747 return false; -748 } -749 if (this.productEvidence != other.productEvidence && (this.productEvidence == null || !this.productEvidence.equals(other.productEvidence))) { -750 return false; -751 } -752 if (this.versionEvidence != other.versionEvidence && (this.versionEvidence == null || !this.versionEvidence.equals(other.versionEvidence))) { -753 return false; -754 } -755 if ((this.description == null) ? (other.description != null) : !this.description.equals(other.description)) { -756 return false; -757 } -758 if ((this.license == null) ? (other.license != null) : !this.license.equals(other.license)) { -759 return false; -760 } -761 if (this.vulnerabilities != other.vulnerabilities && (this.vulnerabilities == null || !this.vulnerabilities.equals(other.vulnerabilities))) { -762 return false; -763 } -764 if (this.relatedDependencies != other.relatedDependencies -765 && (this.relatedDependencies == null || !this.relatedDependencies.equals(other.relatedDependencies))) { -766 return false; -767 } -768 if (this.projectReferences != other.projectReferences -769 && (this.projectReferences == null || !this.projectReferences.equals(other.projectReferences))) { -770 return false; -771 } -772 if (this.availableVersions != other.availableVersions -773 && (this.availableVersions == null || !this.availableVersions.equals(other.availableVersions))) { -774 return false; -775 } -776 -777 return true; -778 } -779 -780 /** -781 * Generates the HashCode. -782 * -783 * @return the HashCode -784 */ -785 @Override -786 public int hashCode() { -787 int hash = 3; -788 hash = 47 * hash + (this.actualFilePath != null ? this.actualFilePath.hashCode() : 0); -789 hash = 47 * hash + (this.filePath != null ? this.filePath.hashCode() : 0); -790 hash = 47 * hash + (this.fileName != null ? this.fileName.hashCode() : 0); -791 hash = 47 * hash + (this.fileExtension != null ? this.fileExtension.hashCode() : 0); -792 hash = 47 * hash + (this.md5sum != null ? this.md5sum.hashCode() : 0); -793 hash = 47 * hash + (this.sha1sum != null ? this.sha1sum.hashCode() : 0); -794 hash = 47 * hash + (this.identifiers != null ? this.identifiers.hashCode() : 0); -795 hash = 47 * hash + (this.vendorEvidence != null ? this.vendorEvidence.hashCode() : 0); -796 hash = 47 * hash + (this.productEvidence != null ? this.productEvidence.hashCode() : 0); -797 hash = 47 * hash + (this.versionEvidence != null ? this.versionEvidence.hashCode() : 0); -798 hash = 47 * hash + (this.description != null ? this.description.hashCode() : 0); -799 hash = 47 * hash + (this.license != null ? this.license.hashCode() : 0); -800 hash = 47 * hash + (this.vulnerabilities != null ? this.vulnerabilities.hashCode() : 0); -801 hash = 47 * hash + (this.relatedDependencies != null ? this.relatedDependencies.hashCode() : 0); -802 hash = 47 * hash + (this.projectReferences != null ? this.projectReferences.hashCode() : 0); -803 hash = 47 * hash + (this.availableVersions != null ? this.availableVersions.hashCode() : 0); -804 return hash; -805 } -806 -807 /** -808 * Standard toString() implementation showing the filename, actualFilePath, and filePath. -809 * -810 * @return the string representation of the file -811 */ -812 @Override -813 public String toString() { -814 return "Dependency{ fileName='" + fileName + "', actualFilePath='" + actualFilePath + "', filePath='" + filePath + "'}"; -815 } -816 } +533 * Set the value of vulnerabilities. +534 * +535 * @param vulnerabilities new value of vulnerabilities +536 */ +537 public void setVulnerabilities(SortedSet<Vulnerability> vulnerabilities) { +538 this.vulnerabilities = vulnerabilities; +539 } +540 +541 /** +542 * Determines the sha1 and md5 sum for the given file. +543 * +544 * @param file the file to create checksums for +545 */ +546 private void determineHashes(File file) { +547 String md5 = null; +548 String sha1 = null; +549 try { +550 md5 = Checksum.getMD5Checksum(file); +551 sha1 = Checksum.getSHA1Checksum(file); +552 } catch (IOException ex) { +553 LOGGER.warn("Unable to read '{}' to determine hashes.", file.getName()); +554 LOGGER.debug("", ex); +555 } catch (NoSuchAlgorithmException ex) { +556 LOGGER.warn("Unable to use MD5 of SHA1 checksums."); +557 LOGGER.debug("", ex); +558 } +559 this.setMd5sum(md5); +560 this.setSha1sum(sha1); +561 } +562 +563 /** +564 * Adds a vulnerability to the dependency. +565 * +566 * @param vulnerability a vulnerability outlining a vulnerability. +567 */ +568 public void addVulnerability(Vulnerability vulnerability) { +569 this.vulnerabilities.add(vulnerability); +570 } +571 +572 /** +573 * A collection of related dependencies. +574 */ +575 private Set<Dependency> relatedDependencies = new TreeSet<Dependency>(); +576 +577 /** +578 * Get the value of {@link #relatedDependencies}. This field is used to collect other dependencies which really represent the +579 * same dependency, and may be presented as one item in reports. +580 * +581 * @return the value of relatedDependencies +582 */ +583 public Set<Dependency> getRelatedDependencies() { +584 return relatedDependencies; +585 } +586 +587 /** +588 * A list of projects that reference this dependency. +589 */ +590 private Set<String> projectReferences = new HashSet<String>(); +591 +592 /** +593 * Get the value of projectReferences. +594 * +595 * @return the value of projectReferences +596 */ +597 public Set<String> getProjectReferences() { +598 return projectReferences; +599 } +600 +601 /** +602 * Set the value of projectReferences. +603 * +604 * @param projectReferences new value of projectReferences +605 */ +606 public void setProjectReferences(Set<String> projectReferences) { +607 this.projectReferences = projectReferences; +608 } +609 +610 /** +611 * Adds a project reference. +612 * +613 * @param projectReference a project reference +614 */ +615 public void addProjectReference(String projectReference) { +616 this.projectReferences.add(projectReference); +617 } +618 +619 /** +620 * Add a collection of project reference. +621 * +622 * @param projectReferences a set of project references +623 */ +624 public void addAllProjectReferences(Set<String> projectReferences) { +625 this.projectReferences.addAll(projectReferences); +626 } +627 +628 /** +629 * Set the value of relatedDependencies. +630 * +631 * @param relatedDependencies new value of relatedDependencies +632 */ +633 public void setRelatedDependencies(Set<Dependency> relatedDependencies) { +634 this.relatedDependencies = relatedDependencies; +635 } +636 +637 /** +638 * Adds a related dependency. The internal collection is normally a {@link java.util.TreeSet}, which relies on +639 * {@link #compareTo(Dependency)}. A consequence of this is that if you attempt to add a dependency with the same file path +640 * (modulo character case) as one that is already in the collection, it won't get added. +641 * +642 * @param dependency a reference to the related dependency +643 */ +644 public void addRelatedDependency(Dependency dependency) { +645 if (this == dependency) { +646 LOGGER.warn("Attempted to add a circular reference - please post the log file to issue #172 here " +647 + "https://github.com/jeremylong/DependencyCheck/issues/172"); +648 LOGGER.debug("this: {}", this); +649 LOGGER.debug("dependency: {}", dependency); +650 } else if (!relatedDependencies.add(dependency)) { +651 LOGGER.debug("Failed to add dependency, likely due to referencing the same file as another dependency in the set."); +652 LOGGER.debug("this: {}", this); +653 LOGGER.debug("dependency: {}", dependency); +654 } +655 } +656 +657 /** +658 * A list of available versions. +659 */ +660 private List<String> availableVersions = new ArrayList<String>(); +661 +662 /** +663 * Get the value of availableVersions. +664 * +665 * @return the value of availableVersions +666 */ +667 public List<String> getAvailableVersions() { +668 return availableVersions; +669 } +670 +671 /** +672 * Set the value of availableVersions. +673 * +674 * @param availableVersions new value of availableVersions +675 */ +676 public void setAvailableVersions(List<String> availableVersions) { +677 this.availableVersions = availableVersions; +678 } +679 +680 /** +681 * Adds a version to the available version list. +682 * +683 * @param version the version to add to the list +684 */ +685 public void addAvailableVersion(String version) { +686 this.availableVersions.add(version); +687 } +688 +689 /** +690 * Implementation of the Comparable<Dependency> interface. The comparison is solely based on the file path. +691 * +692 * @param o a dependency to compare +693 * @return an integer representing the natural ordering +694 */ +695 public int compareTo(Dependency o) { +696 return this.getFilePath().compareToIgnoreCase(o.getFilePath()); +697 } +698 +699 /** +700 * Implementation of the equals method. +701 * +702 * @param obj the object to compare +703 * @return true if the objects are equal, otherwise false +704 */ +705 @Override +706 public boolean equals(Object obj) { +707 if (obj == null || getClass() != obj.getClass()) { +708 return false; +709 } +710 final Dependency other = (Dependency) obj; +711 return ObjectUtils.equals(this.actualFilePath, other.actualFilePath) +712 && ObjectUtils.equals(this.filePath, other.filePath) +713 && ObjectUtils.equals(this.fileName, other.fileName) +714 && ObjectUtils.equals(this.md5sum, other.md5sum) +715 && ObjectUtils.equals(this.sha1sum, other.sha1sum) +716 && ObjectUtils.equals(this.identifiers, other.identifiers) +717 && ObjectUtils.equals(this.vendorEvidence, other.vendorEvidence) +718 && ObjectUtils.equals(this.productEvidence, other.productEvidence) +719 && ObjectUtils.equals(this.versionEvidence, other.versionEvidence) +720 && ObjectUtils.equals(this.description, other.description) +721 && ObjectUtils.equals(this.license, other.license) +722 && ObjectUtils.equals(this.vulnerabilities, other.vulnerabilities) +723 && ObjectUtils.equals(this.relatedDependencies, other.relatedDependencies) +724 && ObjectUtils.equals(this.projectReferences, other.projectReferences) +725 && ObjectUtils.equals(this.availableVersions, other.availableVersions); +726 } +727 +728 /** +729 * Generates the HashCode. +730 * +731 * @return the HashCode +732 */ +733 @Override +734 public int hashCode() { +735 int hash = MAGIC_HASH_INIT_VALUE; +736 for (Object field : new Object[]{this.actualFilePath, this.filePath, this.fileName, this.md5sum, +737 this.sha1sum, this.identifiers, this.vendorEvidence, this.productEvidence, this.versionEvidence, +738 this.description, this.license, this.vulnerabilities, this.relatedDependencies, this.projectReferences, +739 this.availableVersions}) { +740 hash = MAGIC_HASH_MULTIPLIER * hash + ObjectUtils.hashCode(field); +741 } +742 return hash; +743 } +744 +745 /** +746 * Standard toString() implementation showing the filename, actualFilePath, and filePath. +747 * +748 * @return the string representation of the file +749 */ +750 @Override +751 public String toString() { +752 return "Dependency{ fileName='" + fileName + "', actualFilePath='" + actualFilePath + "', filePath='" + filePath + "'}"; +753 } +754 }
    diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/dependency/Evidence.html b/dependency-check-core/xref/org/owasp/dependencycheck/dependency/Evidence.html index 39e4312b0..545c79813 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/dependency/Evidence.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/dependency/Evidence.html @@ -25,313 +25,271 @@ 17 */ 18 package org.owasp.dependencycheck.dependency; 19 -20 import java.io.Serializable; -21 -22 /** -23 * Evidence is a piece of information about a Dependency. -24 * -25 * @author Jeremy Long -26 */ -27 public class Evidence implements Serializable, Comparable<Evidence> { -28 -29 /** -30 * Creates a new Evidence object. -31 */ -32 public Evidence() { -33 } -34 -35 /** -36 * Creates a new Evidence objects. -37 * -38 * @param source the source of the evidence. -39 * @param name the name of the evidence. -40 * @param value the value of the evidence. -41 * @param confidence the confidence of the evidence. -42 */ -43 public Evidence(String source, String name, String value, Confidence confidence) { -44 this.source = source; -45 this.name = name; -46 this.value = value; -47 this.confidence = confidence; -48 } -49 /** -50 * The name of the evidence. -51 */ -52 private String name; -53 -54 /** -55 * Get the value of name. -56 * -57 * @return the value of name -58 */ -59 public String getName() { -60 return name; +20 import org.apache.commons.lang.ObjectUtils; +21 import org.apache.commons.lang.StringUtils; +22 +23 import java.io.Serializable; +24 +25 /** +26 * Evidence is a piece of information about a Dependency. +27 * +28 * @author Jeremy Long +29 */ +30 public class Evidence implements Serializable, Comparable<Evidence> { +31 +32 /** +33 * Used as starting point for generating the value in {@link #hashCode()}. +34 */ +35 private static final int MAGIC_HASH_INIT_VALUE = 3; +36 +37 /** +38 * Used as a multiplier for generating the value in {@link #hashCode()}. +39 */ +40 private static final int MAGIC_HASH_MULTIPLIER = 67; +41 +42 /** +43 * Creates a new Evidence object. +44 */ +45 public Evidence() { +46 } +47 +48 /** +49 * Creates a new Evidence objects. +50 * +51 * @param source the source of the evidence. +52 * @param name the name of the evidence. +53 * @param value the value of the evidence. +54 * @param confidence the confidence of the evidence. +55 */ +56 public Evidence(String source, String name, String value, Confidence confidence) { +57 this.source = source; +58 this.name = name; +59 this.value = value; +60 this.confidence = confidence; 61 } 62 63 /** -64 * Set the value of name. -65 * -66 * @param name new value of name -67 */ -68 public void setName(String name) { -69 this.name = name; -70 } -71 /** -72 * The source of the evidence. -73 */ -74 private String source; -75 -76 /** -77 * Get the value of source. -78 * -79 * @return the value of source -80 */ -81 public String getSource() { -82 return source; -83 } -84 -85 /** -86 * Set the value of source. -87 * -88 * @param source new value of source -89 */ -90 public void setSource(String source) { -91 this.source = source; -92 } -93 /** -94 * The value of the evidence. +64 * The name of the evidence. +65 */ +66 private String name; +67 +68 /** +69 * Get the value of name. +70 * +71 * @return the value of name +72 */ +73 public String getName() { +74 return name; +75 } +76 +77 /** +78 * Set the value of name. +79 * +80 * @param name new value of name +81 */ +82 public void setName(String name) { +83 this.name = name; +84 } +85 +86 /** +87 * The source of the evidence. +88 */ +89 private String source; +90 +91 /** +92 * Get the value of source. +93 * +94 * @return the value of source 95 */ -96 private String value; -97 -98 /** -99 * Get the value of value. -100 * -101 * @return the value of value -102 */ -103 public String getValue() { -104 used = true; -105 return value; -106 } -107 -108 /** -109 * Get the value of value. If setUsed is set to false this call to get will not mark the evidence as used. -110 * -111 * @param setUsed whether or not this call to getValue should cause the used flag to be updated -112 * @return the value of value -113 */ -114 public String getValue(Boolean setUsed) { -115 used = used || setUsed; -116 return value; -117 } -118 -119 /** -120 * Set the value of value. -121 * -122 * @param value new value of value -123 */ -124 public void setValue(String value) { -125 this.value = value; -126 } -127 /** -128 * A value indicating if the Evidence has been "used" (aka read). +96 public String getSource() { +97 return source; +98 } +99 +100 /** +101 * Set the value of source. +102 * +103 * @param source new value of source +104 */ +105 public void setSource(String source) { +106 this.source = source; +107 } +108 +109 /** +110 * The value of the evidence. +111 */ +112 private String value; +113 +114 /** +115 * Get the value of value. +116 * +117 * @return the value of value +118 */ +119 public String getValue() { +120 used = true; +121 return value; +122 } +123 +124 /** +125 * Get the value of value. If setUsed is set to false this call to get will not mark the evidence as used. +126 * +127 * @param setUsed whether or not this call to getValue should cause the used flag to be updated +128 * @return the value of value 129 */ -130 private boolean used; -131 -132 /** -133 * Get the value of used. -134 * -135 * @return the value of used -136 */ -137 public boolean isUsed() { -138 return used; -139 } -140 -141 /** -142 * Set the value of used. -143 * -144 * @param used new value of used -145 */ -146 public void setUsed(boolean used) { -147 this.used = used; -148 } +130 public String getValue(Boolean setUsed) { +131 used = used || setUsed; +132 return value; +133 } +134 +135 /** +136 * Set the value of value. +137 * +138 * @param value new value of value +139 */ +140 public void setValue(String value) { +141 this.value = value; +142 } +143 +144 /** +145 * A value indicating if the Evidence has been "used" (aka read). +146 */ +147 private boolean used; +148 149 /** -150 * The confidence level for the evidence. -151 */ -152 private Confidence confidence; -153 -154 /** -155 * Get the value of confidence. -156 * -157 * @return the value of confidence -158 */ -159 public Confidence getConfidence() { -160 return confidence; -161 } -162 -163 /** -164 * Set the value of confidence. -165 * -166 * @param confidence new value of confidence -167 */ -168 public void setConfidence(Confidence confidence) { -169 this.confidence = confidence; -170 } +150 * Get the value of used. +151 * +152 * @return the value of used +153 */ +154 public boolean isUsed() { +155 return used; +156 } +157 +158 /** +159 * Set the value of used. +160 * +161 * @param used new value of used +162 */ +163 public void setUsed(boolean used) { +164 this.used = used; +165 } +166 +167 /** +168 * The confidence level for the evidence. +169 */ +170 private Confidence confidence; 171 172 /** -173 * Implements the hashCode for Evidence. +173 * Get the value of confidence. 174 * -175 * @return hash code. +175 * @return the value of confidence 176 */ -177 @Override -178 public int hashCode() { -179 int hash = 3; -180 hash = 67 * hash + (this.name != null ? this.name.hashCode() : 0); -181 hash = 67 * hash + (this.source != null ? this.source.hashCode() : 0); -182 hash = 67 * hash + (this.value != null ? this.value.hashCode() : 0); -183 hash = 67 * hash + (this.confidence != null ? this.confidence.hashCode() : 0); -184 return hash; -185 } -186 -187 /** -188 * Implements equals for Evidence. -189 * -190 * @param that an object to check the equality of. -191 * @return whether the two objects are equal. -192 */ -193 @Override -194 public boolean equals(Object that) { -195 if (this == that) { -196 return true; -197 } -198 if (!(that instanceof Evidence)) { -199 return false; -200 } -201 final Evidence e = (Evidence) that; -202 -203 return testEquality(name, e.name) && testEquality(source, e.source) && testEquality(value, e.value) -204 && (confidence == null ? e.confidence == null : confidence == e.confidence); -205 } -206 -207 /** -208 * Simple equality test for use within the equals method. This does a case insensitive compare. -209 * -210 * @param l a string to compare. -211 * @param r another string to compare. -212 * @return whether the two strings are the same. -213 */ -214 private boolean testEquality(String l, String r) { -215 return l == null ? r == null : l.equalsIgnoreCase(r); -216 } -217 -218 /** -219 * Implementation of the comparable interface. -220 * -221 * @param o the evidence being compared -222 * @return an integer indicating the ordering of the two objects -223 */ -224 public int compareTo(Evidence o) { -225 if (o == null) { -226 return 1; -227 } -228 if (equalsWithNullCheck(source, o.source)) { -229 if (equalsWithNullCheck(name, o.name)) { -230 if (equalsWithNullCheck(value, o.value)) { -231 if (equalsWithNullCheck(confidence, o.confidence)) { -232 return 0; //they are equal -233 } else { -234 return compareToWithNullCheck(confidence, o.confidence); -235 } -236 } else { -237 return compareToIgnoreCaseWithNullCheck(value, o.value); -238 } -239 } else { -240 return compareToIgnoreCaseWithNullCheck(name, o.name); -241 } -242 } else { -243 return compareToIgnoreCaseWithNullCheck(source, o.source); -244 } -245 } -246 -247 /** -248 * Equality check with an exhaustive, possibly duplicative, check against nulls. -249 * -250 * @param me the value to be compared -251 * @param other the other value to be compared -252 * @return true if the values are equal; otherwise false -253 */ -254 private boolean equalsWithNullCheck(String me, String other) { -255 if (me == null && other == null) { -256 return true; -257 } else if (me == null || other == null) { -258 return false; -259 } -260 return me.equalsIgnoreCase(other); -261 } -262 -263 /** -264 * Equality check with an exhaustive, possibly duplicative, check against nulls. -265 * -266 * @param me the value to be compared -267 * @param other the other value to be compared -268 * @return true if the values are equal; otherwise false -269 */ -270 private boolean equalsWithNullCheck(Confidence me, Confidence other) { -271 if (me == null && other == null) { -272 return true; -273 } else if (me == null || other == null) { -274 return false; -275 } -276 return me.equals(other); -277 } -278 -279 /** -280 * Wrapper around {@link java.lang.String#compareToIgnoreCase(java.lang.String) String.compareToIgnoreCase} with an -281 * exhaustive, possibly duplicative, check against nulls. -282 * -283 * @param me the value to be compared -284 * @param other the other value to be compared -285 * @return true if the values are equal; otherwise false -286 */ -287 private int compareToIgnoreCaseWithNullCheck(String me, String other) { -288 if (me == null && other == null) { -289 return 0; -290 } else if (me == null) { -291 return -1; //the other string is greater then me -292 } else if (other == null) { -293 return 1; //me is greater then the other string -294 } -295 return me.compareToIgnoreCase(other); -296 } -297 -298 /** -299 * Wrapper around {@link java.lang.Enum#compareTo(java.lang.Enum) Enum.compareTo} with an exhaustive, possibly duplicative, -300 * check against nulls. -301 * -302 * @param me the value to be compared -303 * @param other the other value to be compared -304 * @return true if the values are equal; otherwise false -305 */ -306 private int compareToWithNullCheck(Confidence me, Confidence other) { -307 if (me == null && other == null) { -308 return 0; -309 } else if (me == null) { -310 return -1; //the other string is greater then me -311 } else if (other == null) { -312 return 1; //me is greater then the other string -313 } -314 return me.compareTo(other); -315 } -316 -317 /** -318 * Standard toString() implementation. -319 * -320 * @return the string representation of the object -321 */ -322 @Override -323 public String toString() { -324 return "Evidence{" + "name=" + name + ", source=" + source + ", value=" + value + ", confidence=" + confidence + '}'; -325 } -326 } +177 public Confidence getConfidence() { +178 return confidence; +179 } +180 +181 /** +182 * Set the value of confidence. +183 * +184 * @param confidence new value of confidence +185 */ +186 public void setConfidence(Confidence confidence) { +187 this.confidence = confidence; +188 } +189 +190 /** +191 * Implements the hashCode for Evidence. +192 * +193 * @return hash code. +194 */ +195 @Override +196 public int hashCode() { +197 int hash = MAGIC_HASH_INIT_VALUE; +198 hash = MAGIC_HASH_MULTIPLIER * hash + ObjectUtils.hashCode(StringUtils.lowerCase(this.name)); +199 hash = MAGIC_HASH_MULTIPLIER * hash + ObjectUtils.hashCode(StringUtils.lowerCase(this.source)); +200 hash = MAGIC_HASH_MULTIPLIER * hash + ObjectUtils.hashCode(StringUtils.lowerCase(this.value)); +201 hash = MAGIC_HASH_MULTIPLIER * hash + ObjectUtils.hashCode(this.confidence); +202 return hash; +203 } +204 +205 /** +206 * Implements equals for Evidence. +207 * +208 * @param that an object to check the equality of. +209 * @return whether the two objects are equal. +210 */ +211 @Override +212 public boolean equals(Object that) { +213 if (this == that) { +214 return true; +215 } +216 if (!(that instanceof Evidence)) { +217 return false; +218 } +219 final Evidence e = (Evidence) that; +220 +221 return StringUtils.equalsIgnoreCase(name, e.name) +222 && StringUtils.equalsIgnoreCase(source, e.source) +223 && StringUtils.equalsIgnoreCase(value, e.value) +224 && ObjectUtils.equals(confidence, e.confidence); +225 } +226 +227 /** +228 * Implementation of the comparable interface. +229 * +230 * @param o the evidence being compared +231 * @return an integer indicating the ordering of the two objects +232 */ +233 public int compareTo(Evidence o) { +234 if (o == null) { +235 return 1; +236 } +237 if (StringUtils.equalsIgnoreCase(source, o.source)) { +238 if (StringUtils.equalsIgnoreCase(name, o.name)) { +239 if (StringUtils.equalsIgnoreCase(value, o.value)) { +240 if (ObjectUtils.equals(confidence, o.confidence)) { +241 return 0; //they are equal +242 } else { +243 return ObjectUtils.compare(confidence, o.confidence); +244 } +245 } else { +246 return compareToIgnoreCaseWithNullCheck(value, o.value); +247 } +248 } else { +249 return compareToIgnoreCaseWithNullCheck(name, o.name); +250 } +251 } else { +252 return compareToIgnoreCaseWithNullCheck(source, o.source); +253 } +254 } +255 +256 /** +257 * Wrapper around {@link java.lang.String#compareToIgnoreCase(java.lang.String) String.compareToIgnoreCase} with an +258 * exhaustive, possibly duplicative, check against nulls. +259 * +260 * @param me the value to be compared +261 * @param other the other value to be compared +262 * @return true if the values are equal; otherwise false +263 */ +264 private int compareToIgnoreCaseWithNullCheck(String me, String other) { +265 if (me == null && other == null) { +266 return 0; +267 } else if (me == null) { +268 return -1; //the other string is greater then me +269 } else if (other == null) { +270 return 1; //me is greater then the other string +271 } +272 return me.compareToIgnoreCase(other); +273 } +274 +275 /** +276 * Standard toString() implementation. +277 * +278 * @return the string representation of the object +279 */ +280 @Override +281 public String toString() { +282 return "Evidence{" + "name=" + name + ", source=" + source + ", value=" + value + ", confidence=" + confidence + '}'; +283 } +284 }
    diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/dependency/EvidenceCollection.html b/dependency-check-core/xref/org/owasp/dependencycheck/dependency/EvidenceCollection.html index 5515bce16..dae4f6ec9 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/dependency/EvidenceCollection.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/dependency/EvidenceCollection.html @@ -32,13 +32,13 @@ 24 import java.util.List; 25 import java.util.Set; 26 import java.util.TreeSet; -27 import java.util.logging.Level; -28 import java.util.logging.Logger; -29 import org.apache.commons.lang.StringUtils; -30 import org.owasp.dependencycheck.utils.DependencyVersion; -31 import org.owasp.dependencycheck.utils.DependencyVersionUtil; -32 import org.owasp.dependencycheck.utils.Filter; -33 import org.owasp.dependencycheck.utils.UrlStringUtils; +27 import org.apache.commons.lang.StringUtils; +28 import org.owasp.dependencycheck.utils.DependencyVersion; +29 import org.owasp.dependencycheck.utils.DependencyVersionUtil; +30 import org.owasp.dependencycheck.utils.Filter; +31 import org.owasp.dependencycheck.utils.UrlStringUtils; +32 import org.slf4j.Logger; +33 import org.slf4j.LoggerFactory; 34 35 /** 36 * Used to maintain a collection of Evidence. @@ -50,7 +50,7 @@ 42 /** 43 * The logger. 44 */ -45 private static final Logger LOGGER = Logger.getLogger(EvidenceCollection.class.getName()); +45 private static final Logger LOGGER = LoggerFactory.getLogger(EvidenceCollection.class); 46 /** 47 * Used to iterate over highest confidence evidence contained in the collection. 48 */ @@ -149,13 +149,13 @@ 141 } 142 143 /** -144 * Adds term to the weighting collection. The terms added here are used later to boost the score of other terms. -145 * This is a way of combining evidence from multiple sources to boost the confidence of the given evidence. +144 * Adds term to the weighting collection. The terms added here are used later to boost the score of other terms. This is a way +145 * of combining evidence from multiple sources to boost the confidence of the given evidence. 146 * -147 * Example: The term 'Apache' is found in the manifest of a JAR and is added to the Collection. When we parse the -148 * package names within the JAR file we may add these package names to the "weighted" strings collection to boost -149 * the score in the Lucene query. That way when we construct the Lucene query we find the term Apache in the -150 * collection AND in the weighted strings; as such, we will boost the confidence of the term Apache. +147 * Example: The term 'Apache' is found in the manifest of a JAR and is added to the Collection. When we parse the package +148 * names within the JAR file we may add these package names to the "weighted" strings collection to boost the score in the +149 * Lucene query. That way when we construct the Lucene query we find the term Apache in the collection AND in the weighted +150 * strings; as such, we will boost the confidence of the term Apache. 151 * 152 * @param str to add to the weighting collection. 153 */ @@ -164,8 +164,8 @@ 156 } 157 158 /** -159 * Returns a set of Weightings - a list of terms that are believed to be of higher confidence when also found in -160 * another location. +159 * Returns a set of Weightings - a list of terms that are believed to be of higher confidence when also found in another +160 * location. 161 * 162 * @return Set<String> 163 */ @@ -330,11 +330,11 @@ 322 final Set<Evidence> ret = new TreeSet<Evidence>(); 323 for (EvidenceCollection col : ec) { 324 for (Evidence e : col) { -325 if (e.isUsed()) { -326 final Evidence newEvidence = new Evidence(e.getSource(), e.getName(), e.getValue(), null); -327 newEvidence.setUsed(true); -328 ret.add(newEvidence); -329 } +325 //if (e.isUsed()) { +326 final Evidence newEvidence = new Evidence(e.getSource(), e.getName(), e.getValue(), null); +327 newEvidence.setUsed(true); +328 ret.add(newEvidence); +329 //} 330 } 331 } 332 return ret; @@ -365,11 +365,11 @@ 357 358 /** 359 * <p> -360 * Takes a string that may contain a fully qualified domain and it will return the string having removed the query -361 * string, the protocol, the sub-domain of 'www', and the file extension of the path.</p> +360 * Takes a string that may contain a fully qualified domain and it will return the string having removed the query string, the +361 * protocol, the sub-domain of 'www', and the file extension of the path.</p> 362 * <p> -363 * This is useful for checking if the evidence contains a specific string. The presence of the protocol, file -364 * extension, etc. may produce false positives. +363 * This is useful for checking if the evidence contains a specific string. The presence of the protocol, file extension, etc. +364 * may produce false positives. 365 * 366 * <p> 367 * Example, given the following input:</p> @@ -393,7 +393,7 @@ 385 final List<String> data = UrlStringUtils.extractImportantUrlData(part); 386 sb.append(' ').append(StringUtils.join(data, ' ')); 387 } catch (MalformedURLException ex) { -388 LOGGER.log(Level.FINE, "error parsing " + part, ex); +388 LOGGER.debug("error parsing {}", part, ex); 389 sb.append(' ').append(part); 390 } 391 } else { 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 d0ebea186..1b5387d45 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/dependency/VulnerableSoftware.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/dependency/VulnerableSoftware.html @@ -28,9 +28,9 @@ 20 import java.io.Serializable; 21 import java.io.UnsupportedEncodingException; 22 import java.net.URLDecoder; -23 import java.util.logging.Level; -24 import java.util.logging.Logger; -25 import org.owasp.dependencycheck.data.cpe.IndexEntry; +23 import org.owasp.dependencycheck.data.cpe.IndexEntry; +24 import org.slf4j.Logger; +25 import org.slf4j.LoggerFactory; 26 27 /** 28 * A record containing information about vulnerable software. This is referenced from a vulnerability. @@ -42,7 +42,7 @@ 34 /** 35 * The logger. 36 */ -37 private static final Logger LOGGER = Logger.getLogger(VulnerableSoftware.class.getName()); +37 private static final Logger LOGGER = LoggerFactory.getLogger(VulnerableSoftware.class); 38 /** 39 * The serial version UID. 40 */ @@ -57,320 +57,329 @@ 49 try { 50 parseName(cpe); 51 } catch (UnsupportedEncodingException ex) { -52 final String msg = String.format("Character encoding is unsupported for CPE '%s'.", cpe); -53 LOGGER.log(Level.WARNING, msg); -54 LOGGER.log(Level.FINE, null, ex); -55 setName(cpe); -56 } -57 } -58 -59 /** -60 * <p> -61 * Parses a name attribute value, from the cpe.xml, into its corresponding parts: vendor, product, version, -62 * revision.</p> -63 * <p> -64 * Example:</p> -65 * <code>&nbsp;&nbsp;&nbsp;cpe:/a:apache:struts:1.1:rc2</code> -66 * -67 * <p> -68 * Results in:</p> <ul> <li>Vendor: apache</li> <li>Product: struts</li> -69 * <li>Version: 1.1</li> <li>Revision: rc2</li> </ul> -70 * -71 * @param cpeName the cpe name -72 * @throws UnsupportedEncodingException should never be thrown... -73 */ -74 @Override -75 public void parseName(String cpeName) throws UnsupportedEncodingException { -76 this.name = cpeName; -77 if (cpeName != null && cpeName.length() > 7) { -78 final String[] data = cpeName.substring(7).split(":"); -79 if (data.length >= 1) { -80 this.setVendor(urlDecode(data[0])); -81 } -82 if (data.length >= 2) { -83 this.setProduct(urlDecode(data[1])); -84 } -85 if (data.length >= 3) { -86 version = urlDecode(data[2]); -87 } -88 if (data.length >= 4) { -89 revision = urlDecode(data[3]); -90 } -91 if (data.length >= 5) { -92 edition = urlDecode(data[4]); -93 } -94 } -95 } -96 /** -97 * If present, indicates that previous version are vulnerable. -98 */ -99 private String previousVersion; -100 -101 /** -102 * Indicates if previous versions of this software are vulnerable. -103 * -104 * @return if previous versions of this software are vulnerable -105 */ -106 public boolean hasPreviousVersion() { -107 return previousVersion != null; -108 } -109 -110 /** -111 * Get the value of previousVersion. -112 * -113 * @return the value of previousVersion -114 */ -115 public String getPreviousVersion() { -116 return previousVersion; -117 } -118 -119 /** -120 * Set the value of previousVersion. -121 * -122 * @param previousVersion new value of previousVersion -123 */ -124 public void setPreviousVersion(String previousVersion) { -125 this.previousVersion = previousVersion; -126 } -127 -128 /** -129 * Standard equals implementation to compare this VulnerableSoftware to another object. -130 * -131 * @param obj the object to compare -132 * @return whether or not the objects are equal -133 */ -134 @Override -135 public boolean equals(Object obj) { -136 if (obj == null) { -137 return false; -138 } -139 if (getClass() != obj.getClass()) { -140 return false; -141 } -142 final VulnerableSoftware other = (VulnerableSoftware) obj; -143 if ((this.getName() == null) ? (other.getName() != null) : !this.getName().equals(other.getName())) { -144 return false; -145 } -146 return true; -147 } -148 -149 /** -150 * Standard implementation of hashCode. -151 * -152 * @return the hashCode for the object -153 */ -154 @Override -155 public int hashCode() { -156 int hash = 7; -157 hash = 83 * hash + (this.getName() != null ? this.getName().hashCode() : 0); -158 return hash; -159 } -160 -161 /** -162 * Standard toString() implementation display the name and whether or not previous versions are also affected. -163 * -164 * @return a string representation of the object -165 */ -166 @Override -167 public String toString() { -168 return "VulnerableSoftware{ name=" + name + ", previousVersion=" + previousVersion + '}'; -169 } -170 -171 /** -172 * Implementation of the comparable interface. -173 * -174 * @param vs the VulnerableSoftware to compare -175 * @return an integer indicating the ordering of the two objects -176 */ -177 @Override -178 public int compareTo(VulnerableSoftware vs) { -179 int result = 0; -180 final String[] left = this.getName().split(":"); -181 final String[] right = vs.getName().split(":"); -182 final int max = (left.length <= right.length) ? left.length : right.length; -183 if (max > 0) { -184 for (int i = 0; result == 0 && i < max; i++) { -185 final String[] subLeft = left[i].split("\\."); -186 final String[] subRight = right[i].split("\\."); -187 final int subMax = (subLeft.length <= subRight.length) ? subLeft.length : subRight.length; -188 if (subMax > 0) { -189 for (int x = 0; result == 0 && x < subMax; x++) { -190 if (isPositiveInteger(subLeft[x]) && isPositiveInteger(subRight[x])) { -191 try { -192 result = Long.valueOf(subLeft[x]).compareTo(Long.valueOf(subRight[x])); -193 // final long iLeft = Long.parseLong(subLeft[x]); -194 // final long iRight = Long.parseLong(subRight[x]); -195 // if (iLeft != iRight) { -196 // if (iLeft > iRight) { -197 // result = 2; -198 // } else { -199 // result = -2; -200 // } -201 // } -202 } catch (NumberFormatException ex) { -203 //ignore the exception - they obviously aren't numbers -204 if (!subLeft[x].equalsIgnoreCase(subRight[x])) { -205 result = subLeft[x].compareToIgnoreCase(subRight[x]); -206 } -207 } -208 } else { -209 result = subLeft[x].compareToIgnoreCase(subRight[x]); -210 } -211 } -212 if (result == 0) { -213 if (subLeft.length > subRight.length) { -214 result = 2; -215 } -216 if (subRight.length > subLeft.length) { -217 result = -2; -218 } -219 } -220 } else { -221 result = left[i].compareToIgnoreCase(right[i]); -222 } -223 } -224 if (result == 0) { -225 if (left.length > right.length) { -226 result = 2; -227 } -228 if (right.length > left.length) { -229 result = -2; -230 } -231 } -232 } else { -233 result = this.getName().compareToIgnoreCase(vs.getName()); -234 } -235 return result; -236 } -237 -238 /** -239 * Determines if the string passed in is a positive integer. -240 * -241 * @param str the string to test -242 * @return true if the string only contains 0-9, otherwise false. -243 */ -244 private static boolean isPositiveInteger(final String str) { -245 if (str == null || str.isEmpty()) { -246 return false; -247 } -248 for (int i = 0; i < str.length(); i++) { -249 final char c = str.charAt(i); -250 if (c < '0' || c > '9') { -251 return false; -252 } -253 } -254 return true; -255 } -256 /** -257 * The name of the cpe. -258 */ -259 private String name; -260 -261 /** -262 * Get the value of name. -263 * -264 * @return the value of name -265 */ -266 public String getName() { -267 return name; -268 } -269 -270 /** -271 * Set the value of name. -272 * -273 * @param name new value of name -274 */ -275 public void setName(String name) { -276 this.name = name; -277 } -278 /** -279 * The product version number. -280 */ -281 private String version; -282 -283 /** -284 * Get the value of version. -285 * -286 * @return the value of version -287 */ -288 public String getVersion() { -289 return version; -290 } -291 -292 /** -293 * Set the value of version. -294 * -295 * @param version new value of version -296 */ -297 public void setVersion(String version) { -298 this.version = version; -299 } -300 /** -301 * The product revision version. -302 */ -303 private String revision; -304 -305 /** -306 * Get the value of revision. -307 * -308 * @return the value of revision -309 */ -310 public String getRevision() { -311 return revision; -312 } -313 -314 /** -315 * Set the value of revision. -316 * -317 * @param revision new value of revision -318 */ -319 public void setRevision(String revision) { -320 this.revision = revision; -321 } -322 /** -323 * The product edition. -324 */ -325 private String edition; -326 -327 /** -328 * Get the value of edition. -329 * -330 * @return the value of edition -331 */ -332 public String getEdition() { -333 return edition; -334 } -335 -336 /** -337 * Set the value of edition. -338 * -339 * @param edition new value of edition -340 */ -341 public void setEdition(String edition) { -342 this.edition = edition; -343 } -344 -345 /** -346 * Replaces '+' with '%2B' and then URL Decodes the string attempting first UTF-8, then ASCII, then default. -347 * -348 * @param string the string to URL Decode -349 * @return the URL Decoded string -350 */ -351 private String urlDecode(String string) { -352 final String text = string.replace("+", "%2B"); -353 String result; -354 try { -355 result = URLDecoder.decode(text, "UTF-8"); -356 } catch (UnsupportedEncodingException ex) { -357 try { -358 result = URLDecoder.decode(text, "ASCII"); -359 } catch (UnsupportedEncodingException ex1) { -360 result = URLDecoder.decode(text); -361 } -362 } -363 return result; -364 } -365 } +52 LOGGER.warn("Character encoding is unsupported for CPE '{}'.", cpe); +53 LOGGER.debug("", ex); +54 setName(cpe); +55 } +56 } +57 +58 /** +59 * <p> +60 * Parses a name attribute value, from the cpe.xml, into its corresponding parts: vendor, product, version, update.</p> +61 * <p> +62 * Example:</p> +63 * <code>&nbsp;&nbsp;&nbsp;cpe:/a:apache:struts:1.1:rc2</code> +64 * +65 * <p> +66 * Results in:</p> <ul> <li>Vendor: apache</li> <li>Product: struts</li> +67 * <li>Version: 1.1</li> <li>Revision: rc2</li> </ul> +68 * +69 * @param cpeName the cpe name +70 * @throws UnsupportedEncodingException should never be thrown... +71 */ +72 @Override +73 public void parseName(String cpeName) throws UnsupportedEncodingException { +74 this.name = cpeName; +75 if (cpeName != null && cpeName.length() > 7) { +76 final String[] data = cpeName.substring(7).split(":"); +77 if (data.length >= 1) { +78 this.setVendor(urlDecode(data[0])); +79 } +80 if (data.length >= 2) { +81 this.setProduct(urlDecode(data[1])); +82 } +83 if (data.length >= 3) { +84 version = urlDecode(data[2]); +85 } +86 if (data.length >= 4) { +87 update = urlDecode(data[3]); +88 } +89 if (data.length >= 5) { +90 edition = urlDecode(data[4]); +91 } +92 } +93 } +94 /** +95 * If present, indicates that previous version are vulnerable. +96 */ +97 private String previousVersion; +98 +99 /** +100 * Indicates if previous versions of this software are vulnerable. +101 * +102 * @return if previous versions of this software are vulnerable +103 */ +104 public boolean hasPreviousVersion() { +105 return previousVersion != null; +106 } +107 +108 /** +109 * Get the value of previousVersion. +110 * +111 * @return the value of previousVersion +112 */ +113 public String getPreviousVersion() { +114 return previousVersion; +115 } +116 +117 /** +118 * Set the value of previousVersion. +119 * +120 * @param previousVersion new value of previousVersion +121 */ +122 public void setPreviousVersion(String previousVersion) { +123 this.previousVersion = previousVersion; +124 } +125 +126 /** +127 * Standard equals implementation to compare this VulnerableSoftware to another object. +128 * +129 * @param obj the object to compare +130 * @return whether or not the objects are equal +131 */ +132 @Override +133 public boolean equals(Object obj) { +134 if (obj == null) { +135 return false; +136 } +137 if (getClass() != obj.getClass()) { +138 return false; +139 } +140 final VulnerableSoftware other = (VulnerableSoftware) obj; +141 if ((this.getName() == null) ? (other.getName() != null) : !this.getName().equals(other.getName())) { +142 return false; +143 } +144 return true; +145 } +146 +147 /** +148 * Standard implementation of hashCode. +149 * +150 * @return the hashCode for the object +151 */ +152 @Override +153 public int hashCode() { +154 int hash = 7; +155 hash = 83 * hash + (this.getName() != null ? this.getName().hashCode() : 0); +156 return hash; +157 } +158 +159 /** +160 * Standard toString() implementation display the name and whether or not previous versions are also affected. +161 * +162 * @return a string representation of the object +163 */ +164 @Override +165 public String toString() { +166 return "VulnerableSoftware{ name=" + name + ", previousVersion=" + previousVersion + '}'; +167 } +168 +169 /** +170 * Implementation of the comparable interface. +171 * +172 * @param vs the VulnerableSoftware to compare +173 * @return an integer indicating the ordering of the two objects +174 */ +175 @Override +176 public int compareTo(VulnerableSoftware vs) { +177 int result = 0; +178 final String[] left = this.getName().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("\\."); +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; +258 +259 /** +260 * Get the value of name. +261 * +262 * @return the value of name +263 */ +264 public String getName() { +265 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 this.name = name; +275 } +276 /** +277 * The product version number. +278 */ +279 private String version; +280 +281 /** +282 * Get the value of version. +283 * +284 * @return the value of version +285 */ +286 public String getVersion() { +287 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 this.version = version; +297 } +298 /** +299 * The product update version. +300 */ +301 private String update; +302 +303 /** +304 * Get the value of update. +305 * +306 * @return the value of update +307 */ +308 public String getUpdate() { +309 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 this.update = update; +319 } +320 /** +321 * The product edition. +322 */ +323 private String edition; +324 +325 /** +326 * Get the value of edition. +327 * +328 * @return the value of edition +329 */ +330 public String getEdition() { +331 return edition; +332 } +333 +334 /** +335 * Set the value of edition. +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 }
    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 a7d168d0a..161182fa5 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.2.11 Reference Package org.owasp.dependencycheck.dependency + Dependency-Check Core 1.3.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 b4819e77a..1a93bcb8b 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.2.11 Reference Package org.owasp.dependencycheck.dependency + Dependency-Check Core 1.3.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 d43e4836c..9232ebd39 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.2.11 Reference Package org.owasp.dependencycheck.exception + Dependency-Check Core 1.3.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 cadbab0d6..cb4fd7108 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.2.11 Reference Package org.owasp.dependencycheck.exception + Dependency-Check Core 1.3.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 1dcdcf2e3..262a68ea1 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.2.11 Reference Package org.owasp.dependencycheck + Dependency-Check Core 1.3.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 89cfd1d32..23d5e3cf8 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.2.11 Reference Package org.owasp.dependencycheck + Dependency-Check Core 1.3.0 Reference Package org.owasp.dependencycheck diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/reporting/EscapeTool.html b/dependency-check-core/xref/org/owasp/dependencycheck/reporting/EscapeTool.html index 884a5fbbe..fd76fd2b5 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/reporting/EscapeTool.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/reporting/EscapeTool.html @@ -27,9 +27,9 @@ 19 20 import java.io.UnsupportedEncodingException; 21 import java.net.URLEncoder; -22 import java.util.logging.Level; -23 import java.util.logging.Logger; -24 import org.apache.commons.lang.StringEscapeUtils; +22 import org.apache.commons.lang.StringEscapeUtils; +23 import org.slf4j.Logger; +24 import org.slf4j.LoggerFactory; 25 26 /** 27 * An extremely simple wrapper around various escape utils to perform URL and HTML encoding within the reports. This @@ -42,7 +42,7 @@ 34 /** 35 * The logger. 36 */ -37 private static final Logger LOGGER = Logger.getLogger(EscapeTool.class.getName()); +37 private static final Logger LOGGER = LoggerFactory.getLogger(EscapeTool.class); 38 39 /** 40 * URL Encodes the provided text. @@ -54,8 +54,8 @@ 46 try { 47 return URLEncoder.encode(text, "UTF-8"); 48 } catch (UnsupportedEncodingException ex) { -49 LOGGER.log(Level.WARNING, "UTF-8 is not supported?"); -50 LOGGER.log(Level.INFO, null, ex); +49 LOGGER.warn("UTF-8 is not supported?"); +50 LOGGER.info("", ex); 51 } 52 return ""; 53 } diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/reporting/ReportGenerator.html b/dependency-check-core/xref/org/owasp/dependencycheck/reporting/ReportGenerator.html index 7c7efd1d3..32a0c8f9f 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/reporting/ReportGenerator.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/reporting/ReportGenerator.html @@ -38,16 +38,16 @@ 30 import java.text.SimpleDateFormat; 31 import java.util.Date; 32 import java.util.List; -33 import java.util.logging.Level; -34 import java.util.logging.Logger; -35 import org.apache.velocity.VelocityContext; -36 import org.apache.velocity.app.VelocityEngine; -37 import org.apache.velocity.context.Context; -38 import org.apache.velocity.runtime.RuntimeConstants; -39 import org.owasp.dependencycheck.analyzer.Analyzer; -40 import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties; -41 import org.owasp.dependencycheck.dependency.Dependency; -42 import org.owasp.dependencycheck.utils.Settings; +33 import org.apache.velocity.VelocityContext; +34 import org.apache.velocity.app.VelocityEngine; +35 import org.apache.velocity.context.Context; +36 import org.apache.velocity.runtime.RuntimeConstants; +37 import org.owasp.dependencycheck.analyzer.Analyzer; +38 import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties; +39 import org.owasp.dependencycheck.dependency.Dependency; +40 import org.owasp.dependencycheck.utils.Settings; +41 import org.slf4j.Logger; +42 import org.slf4j.LoggerFactory; 43 44 /** 45 * The ReportGenerator is used to, as the name implies, generate reports. Internally the generator uses the Velocity @@ -60,7 +60,7 @@ 52 /** 53 * The logger. 54 */ -55 private static final Logger LOGGER = Logger.getLogger(ReportGenerator.class.getName()); +55 private static final Logger LOGGER = LoggerFactory.getLogger(ReportGenerator.class); 56 57 /** 58 * An enumeration of the report formats. @@ -243,88 +243,87 @@ 235 templatePath = templateName; 236 input = new FileInputStream(f); 237 } catch (FileNotFoundException ex) { -238 final String msg = "Unable to generate the report, the report template file could not be found."; -239 LOGGER.log(Level.SEVERE, msg); -240 LOGGER.log(Level.FINE, null, ex); -241 } -242 } else { -243 templatePath = "templates/" + templateName + ".vsl"; -244 input = this.getClass().getClassLoader().getResourceAsStream(templatePath); -245 } -246 if (input == null) { -247 throw new IOException("Template file doesn't exist"); -248 } -249 -250 final InputStreamReader reader = new InputStreamReader(input, "UTF-8"); -251 OutputStreamWriter writer = null; -252 -253 try { -254 writer = new OutputStreamWriter(outputStream, "UTF-8"); -255 -256 if (!engine.evaluate(context, writer, templatePath, reader)) { -257 throw new Exception("Failed to convert the template into html."); -258 } -259 writer.flush(); -260 } finally { -261 if (writer != null) { -262 try { -263 writer.close(); -264 } catch (IOException ex) { -265 LOGGER.log(Level.FINEST, null, ex); -266 } -267 } -268 if (outputStream != null) { -269 try { -270 outputStream.close(); -271 } catch (IOException ex) { -272 LOGGER.log(Level.FINEST, null, ex); -273 } -274 } -275 try { -276 reader.close(); -277 } catch (IOException ex) { -278 LOGGER.log(Level.FINEST, null, ex); -279 } -280 } -281 } -282 -283 /** -284 * Generates a report from a given Velocity Template. The template name provided can be the name of a template -285 * contained in the jar file, such as 'XmlReport' or 'HtmlReport', or the template name can be the path to a -286 * template file. -287 * -288 * @param templateName the name of the template to load. -289 * @param outFileName the filename and path to write the report to. -290 * @throws IOException is thrown when the template file does not exist. -291 * @throws Exception is thrown when an exception occurs. -292 */ -293 protected void generateReport(String templateName, String outFileName) throws Exception { -294 File outFile = new File(outFileName); -295 if (outFile.getParentFile() == null) { -296 outFile = new File(".", outFileName); -297 } -298 if (!outFile.getParentFile().exists()) { -299 final boolean created = outFile.getParentFile().mkdirs(); -300 if (!created) { -301 throw new Exception("Unable to create directory '" + outFile.getParentFile().getAbsolutePath() + "'."); -302 } -303 } -304 -305 OutputStream outputSteam = null; -306 try { -307 outputSteam = new FileOutputStream(outFile); -308 generateReport(templateName, outputSteam); -309 } finally { -310 if (outputSteam != null) { -311 try { -312 outputSteam.close(); -313 } catch (IOException ex) { -314 LOGGER.log(Level.FINEST, "ignore", ex); -315 } -316 } -317 } -318 } -319 } +238 LOGGER.error("Unable to generate the report, the report template file could not be found."); +239 LOGGER.debug("", ex); +240 } +241 } else { +242 templatePath = "templates/" + templateName + ".vsl"; +243 input = this.getClass().getClassLoader().getResourceAsStream(templatePath); +244 } +245 if (input == null) { +246 throw new IOException("Template file doesn't exist"); +247 } +248 +249 final InputStreamReader reader = new InputStreamReader(input, "UTF-8"); +250 OutputStreamWriter writer = null; +251 +252 try { +253 writer = new OutputStreamWriter(outputStream, "UTF-8"); +254 +255 if (!engine.evaluate(context, writer, templatePath, reader)) { +256 throw new Exception("Failed to convert the template into html."); +257 } +258 writer.flush(); +259 } finally { +260 if (writer != null) { +261 try { +262 writer.close(); +263 } catch (IOException ex) { +264 LOGGER.trace("", ex); +265 } +266 } +267 if (outputStream != null) { +268 try { +269 outputStream.close(); +270 } catch (IOException ex) { +271 LOGGER.trace("", ex); +272 } +273 } +274 try { +275 reader.close(); +276 } catch (IOException ex) { +277 LOGGER.trace("", ex); +278 } +279 } +280 } +281 +282 /** +283 * Generates a report from a given Velocity Template. The template name provided can be the name of a template +284 * contained in the jar file, such as 'XmlReport' or 'HtmlReport', or the template name can be the path to a +285 * template file. +286 * +287 * @param templateName the name of the template to load. +288 * @param outFileName the filename and path to write the report to. +289 * @throws IOException is thrown when the template file does not exist. +290 * @throws Exception is thrown when an exception occurs. +291 */ +292 protected void generateReport(String templateName, String outFileName) throws Exception { +293 File outFile = new File(outFileName); +294 if (outFile.getParentFile() == null) { +295 outFile = new File(".", outFileName); +296 } +297 if (!outFile.getParentFile().exists()) { +298 final boolean created = outFile.getParentFile().mkdirs(); +299 if (!created) { +300 throw new Exception("Unable to create directory '" + outFile.getParentFile().getAbsolutePath() + "'."); +301 } +302 } +303 +304 OutputStream outputSteam = null; +305 try { +306 outputSteam = new FileOutputStream(outFile); +307 generateReport(templateName, outputSteam); +308 } finally { +309 if (outputSteam != null) { +310 try { +311 outputSteam.close(); +312 } catch (IOException ex) { +313 LOGGER.trace("ignore", ex); +314 } +315 } +316 } +317 } +318 }
    diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/reporting/VelocityLoggerRedirect.html b/dependency-check-core/xref/org/owasp/dependencycheck/reporting/VelocityLoggerRedirect.html index dc058255f..dc2357039 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/reporting/VelocityLoggerRedirect.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/reporting/VelocityLoggerRedirect.html @@ -25,14 +25,14 @@ 17 */ 18 package org.owasp.dependencycheck.reporting; 19 -20 import java.util.logging.Level; -21 import java.util.logging.Logger; -22 import org.apache.velocity.runtime.RuntimeServices; -23 import org.apache.velocity.runtime.log.LogChute; +20 import org.apache.velocity.runtime.RuntimeServices; +21 import org.apache.velocity.runtime.log.LogChute; +22 import org.slf4j.Logger; +23 import org.slf4j.LoggerFactory; 24 25 /** 26 * <p> -27 * DependencyCheck uses {@link java.util.logging.Logger} as a logging framework, and Apache Velocity uses a custom +27 * DependencyCheck uses {@link org.slf4j.Logger} as a logging framework, and Apache Velocity uses a custom 28 * logging implementation that outputs to a file named velocity.log by default. This class is an implementation of a 29 * custom Velocity logger that redirects all velocity logging to the Java Logger class. 30 * </p><p> @@ -47,7 +47,7 @@ 39 /** 40 * The Logger. 41 */ -42 private static final Logger LOGGER = Logger.getLogger(VelocityLoggerRedirect.class.getName()); +42 private static final Logger LOGGER = LoggerFactory.getLogger(VelocityLoggerRedirect.class); 43 44 /** 45 * This will be invoked once by the LogManager. @@ -66,54 +66,67 @@ 58 * @param message the message to be logged 59 */ 60 public void log(int level, String message) { -61 LOGGER.log(getLevel(level), message); -62 } -63 -64 /** -65 * Given a Velocity log level, message and Throwable, this method will call the appropriate Logger level and log the -66 * specified values. -67 * -68 * @param level the logging level -69 * @param message the message to be logged -70 * @param t a throwable to log -71 */ -72 public void log(int level, String message, Throwable t) { -73 LOGGER.log(getLevel(level), message, t); -74 } -75 -76 /** -77 * Will always return true. The property file will decide what level to log. -78 * -79 * @param level the logging level -80 * @return true -81 */ -82 public boolean isLevelEnabled(int level) { -83 return true; -84 } -85 -86 /** -87 * Maps Velocity log levels to {@link Logger} values. -88 * -89 * @param velocityLevel the logging level -90 * @return the logging level -91 */ -92 private Level getLevel(int velocityLevel) { -93 switch (velocityLevel) { -94 case TRACE_ID: -95 return Level.ALL; -96 case DEBUG_ID: -97 return Level.FINE; +61 switch (level) { +62 case TRACE_ID: +63 LOGGER.trace(message); +64 break; +65 case DEBUG_ID: +66 LOGGER.debug(message); +67 break; +68 case INFO_ID: +69 LOGGER.info(message); +70 break; +71 case WARN_ID: +72 LOGGER.warn(message); +73 break; +74 case ERROR_ID: +75 LOGGER.error(message); +76 break; +77 default: +78 LOGGER.info(message); +79 } +80 } +81 +82 /** +83 * Given a Velocity log level, message and Throwable, this method will call the appropriate Logger level and log the +84 * specified values. +85 * +86 * @param level the logging level +87 * @param message the message to be logged +88 * @param t a throwable to log +89 */ +90 public void log(int level, String message, Throwable t) { +91 switch (level) { +92 case TRACE_ID: +93 LOGGER.trace(message, t); +94 break; +95 case DEBUG_ID: +96 LOGGER.debug(message, t); +97 break; 98 case INFO_ID: -99 return Level.INFO; -100 case WARN_ID: -101 return Level.WARNING; -102 case ERROR_ID: -103 return Level.SEVERE; -104 default: -105 return Level.INFO; -106 } -107 } -108 } +99 LOGGER.info(message, t); +100 break; +101 case WARN_ID: +102 LOGGER.warn(message, t); +103 break; +104 case ERROR_ID: +105 LOGGER.error(message, t); +106 break; +107 default: +108 LOGGER.info(message, t); +109 } +110 } +111 +112 /** +113 * Will always return true. The property file will decide what level to log. +114 * +115 * @param level the logging level +116 * @return true +117 */ +118 public boolean isLevelEnabled(int level) { +119 return true; +120 } +121 }
    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 19188145f..a041caa9b 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.2.11 Reference Package org.owasp.dependencycheck.reporting + Dependency-Check Core 1.3.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 d95b227e5..c50b9a962 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.2.11 Reference Package org.owasp.dependencycheck.reporting + Dependency-Check Core 1.3.0 Reference Package org.owasp.dependencycheck.reporting diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/suppression/SuppressionErrorHandler.html b/dependency-check-core/xref/org/owasp/dependencycheck/suppression/SuppressionErrorHandler.html index 5214ce500..d8777c026 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/suppression/SuppressionErrorHandler.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/suppression/SuppressionErrorHandler.html @@ -25,8 +25,8 @@ 17 */ 18 package org.owasp.dependencycheck.suppression; 19 -20 import java.util.logging.Level; -21 import java.util.logging.Logger; +20 import org.slf4j.Logger; +21 import org.slf4j.LoggerFactory; 22 import org.xml.sax.ErrorHandler; 23 import org.xml.sax.SAXException; 24 import org.xml.sax.SAXParseException; @@ -41,7 +41,7 @@ 33 /** 34 * The logger. 35 */ -36 private static final Logger LOGGER = Logger.getLogger(SuppressionErrorHandler.class.getName()); +36 private static final Logger LOGGER = LoggerFactory.getLogger(SuppressionErrorHandler.class); 37 38 /** 39 * Builds a prettier exception message. @@ -78,7 +78,7 @@ 70 */ 71 @Override 72 public void warning(SAXParseException ex) throws SAXException { -73 LOGGER.log(Level.FINE, null, ex); +73 LOGGER.debug("", ex); 74 } 75 76 /** 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 8246e9a61..a5bf8eb02 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/suppression/SuppressionParser.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/suppression/SuppressionParser.html @@ -33,108 +33,109 @@ 25 import java.io.InputStreamReader; 26 import java.io.Reader; 27 import java.util.List; -28 import java.util.logging.Level; -29 import java.util.logging.Logger; -30 import javax.xml.parsers.ParserConfigurationException; -31 import javax.xml.parsers.SAXParser; -32 import javax.xml.parsers.SAXParserFactory; -33 import org.xml.sax.InputSource; -34 import org.xml.sax.SAXException; -35 import org.xml.sax.XMLReader; -36 -37 /** -38 * A simple validating parser for XML Suppression Rules. -39 * -40 * @author Jeremy Long -41 */ -42 public class SuppressionParser { -43 -44 /** -45 * The logger. -46 */ -47 private static final Logger LOGGER = Logger.getLogger(SuppressionParser.class.getName()); -48 /** -49 * JAXP Schema Language. Source: http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html -50 */ -51 public static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage"; -52 /** -53 * W3C XML Schema. Source: http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html -54 */ -55 public static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema"; -56 /** -57 * JAXP Schema Source. Source: http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html -58 */ -59 public static final String JAXP_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource"; -60 -61 /** -62 * Parses the given xml file and returns a list of the suppression rules contained. -63 * -64 * @param file an xml file containing suppression rules -65 * @return a list of suppression rules -66 * @throws SuppressionParseException thrown if the xml file cannot be parsed -67 */ -68 public List<SuppressionRule> parseSuppressionRules(File file) throws SuppressionParseException { -69 FileInputStream fis = null; -70 try { -71 fis = new FileInputStream(file); -72 return parseSuppressionRules(fis); -73 } catch (IOException ex) { -74 LOGGER.log(Level.FINE, null, ex); -75 throw new SuppressionParseException(ex); -76 } finally { -77 if (fis != null) { -78 try { -79 fis.close(); -80 } catch (IOException ex) { -81 LOGGER.log(Level.FINE, "Unable to close stream", ex); -82 } -83 } -84 } -85 } -86 -87 /** -88 * Parses the given xml stream and returns a list of the suppression rules contained. -89 * -90 * @param inputStream an InputStream containing suppression rues -91 * @return a list of suppression rules -92 * @throws SuppressionParseException if the xml cannot be parsed -93 */ -94 public List<SuppressionRule> parseSuppressionRules(InputStream inputStream) throws SuppressionParseException { -95 try { -96 final InputStream schemaStream = this.getClass().getClassLoader().getResourceAsStream("schema/suppression.xsd"); -97 final SuppressionHandler handler = new SuppressionHandler(); -98 final SAXParserFactory factory = SAXParserFactory.newInstance(); -99 factory.setNamespaceAware(true); -100 factory.setValidating(true); -101 final SAXParser saxParser = factory.newSAXParser(); -102 saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_LANGUAGE, SuppressionParser.W3C_XML_SCHEMA); -103 saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_SOURCE, new InputSource(schemaStream)); -104 final XMLReader xmlReader = saxParser.getXMLReader(); -105 xmlReader.setErrorHandler(new SuppressionErrorHandler()); -106 xmlReader.setContentHandler(handler); -107 -108 final Reader reader = new InputStreamReader(inputStream, "UTF-8"); -109 final InputSource in = new InputSource(reader); -110 //in.setEncoding("UTF-8"); -111 -112 xmlReader.parse(in); -113 -114 return handler.getSuppressionRules(); -115 } catch (ParserConfigurationException ex) { -116 LOGGER.log(Level.FINE, null, ex); -117 throw new SuppressionParseException(ex); -118 } catch (SAXException ex) { -119 LOGGER.log(Level.FINE, null, ex); -120 throw new SuppressionParseException(ex); -121 } catch (FileNotFoundException ex) { -122 LOGGER.log(Level.FINE, null, ex); -123 throw new SuppressionParseException(ex); -124 } catch (IOException ex) { -125 LOGGER.log(Level.FINE, null, ex); -126 throw new SuppressionParseException(ex); -127 } -128 } -129 } +28 import javax.xml.parsers.ParserConfigurationException; +29 import javax.xml.parsers.SAXParser; +30 import javax.xml.parsers.SAXParserFactory; +31 +32 import org.slf4j.Logger; +33 import org.slf4j.LoggerFactory; +34 import org.xml.sax.InputSource; +35 import org.xml.sax.SAXException; +36 import org.xml.sax.XMLReader; +37 +38 /** +39 * A simple validating parser for XML Suppression Rules. +40 * +41 * @author Jeremy Long +42 */ +43 public class SuppressionParser { +44 +45 /** +46 * The logger. +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 }
    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 03e219091..eec5b0d52 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.2.11 Reference Package org.owasp.dependencycheck.suppression + Dependency-Check Core 1.3.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 fc95e7d91..7563f2d13 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.2.11 Reference Package org.owasp.dependencycheck.suppression + Dependency-Check Core 1.3.0 Reference Package org.owasp.dependencycheck.suppression diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/utils/DBUtils.html b/dependency-check-core/xref/org/owasp/dependencycheck/utils/DBUtils.html index 07743b1a1..314e8f591 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/utils/DBUtils.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/utils/DBUtils.html @@ -29,9 +29,9 @@ 21 import java.sql.ResultSet; 22 import java.sql.SQLException; 23 import java.sql.Statement; -24 import java.util.logging.Level; -25 import java.util.logging.Logger; -26 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; +24 import org.owasp.dependencycheck.data.nvdcve.DatabaseException; +25 import org.slf4j.Logger; +26 import org.slf4j.LoggerFactory; 27 28 /** 29 * @@ -42,7 +42,7 @@ 34 /** 35 * The logger. 36 */ -37 private static final Logger LOGGER = Logger.getLogger(DBUtils.class.getName()); +37 private static final Logger LOGGER = LoggerFactory.getLogger(DBUtils.class); 38 39 /** 40 * Private constructor for a utility class. @@ -84,7 +84,7 @@ 76 try { 77 statement.close(); 78 } catch (SQLException ex) { -79 LOGGER.log(Level.FINEST, statement.toString(), ex); +79 LOGGER.trace(statement.toString(), ex); 80 } 81 } 82 } @@ -99,7 +99,7 @@ 91 try { 92 rs.close(); 93 } catch (SQLException ex) { -94 LOGGER.log(Level.FINEST, rs.toString(), ex); +94 LOGGER.trace(rs.toString(), ex); 95 } 96 } 97 } diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/utils/ExtractionUtil.html b/dependency-check-core/xref/org/owasp/dependencycheck/utils/ExtractionUtil.html index 415ae735d..8f70102b7 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/utils/ExtractionUtil.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/utils/ExtractionUtil.html @@ -25,297 +25,290 @@ 17 */ 18 package org.owasp.dependencycheck.utils; 19 -20 import static org.owasp.dependencycheck.utils.FileUtils.getFileExtension; -21 -22 import java.io.BufferedInputStream; -23 import java.io.BufferedOutputStream; -24 import java.io.Closeable; -25 import java.io.File; -26 import java.io.FileInputStream; -27 import java.io.FileNotFoundException; -28 import java.io.FileOutputStream; -29 import java.io.FilenameFilter; -30 import java.io.IOException; -31 import java.io.InputStream; -32 import java.util.logging.Level; -33 import java.util.logging.Logger; -34 import java.util.zip.ZipEntry; -35 import java.util.zip.ZipInputStream; -36 -37 import org.apache.commons.compress.archivers.ArchiveEntry; -38 import org.apache.commons.compress.archivers.ArchiveInputStream; -39 import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream; -40 import org.owasp.dependencycheck.Engine; -41 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; -42 import org.owasp.dependencycheck.analyzer.exception.ArchiveExtractionException; -43 -44 /** -45 * Set of utilities to extract files from archives. -46 * -47 * @author Jeremy Long -48 */ -49 public final class ExtractionUtil { -50 -51 /** -52 * The logger. -53 */ -54 private static final Logger LOGGER = Logger.getLogger(ExtractionUtil.class.getName()); -55 /** -56 * The buffer size to use when extracting files from the archive. -57 */ -58 private static final int BUFFER_SIZE = 4096; -59 -60 /** -61 * Private constructor for a utility class. -62 */ -63 private ExtractionUtil() { -64 } -65 -66 /** -67 * Extracts the contents of an archive into the specified directory. -68 * -69 * @param archive an archive file such as a WAR or EAR -70 * @param extractTo a directory to extract the contents to -71 * @throws ExtractionException thrown if an exception occurs while extracting the files -72 */ -73 public static void extractFiles(File archive, File extractTo) throws ExtractionException { -74 extractFiles(archive, extractTo, null); -75 } -76 -77 /** -78 * Extracts the contents of an archive into the specified directory. The files are only extracted if they are supported by the -79 * analyzers loaded into the specified engine. If the engine is specified as null then all files are extracted. -80 * -81 * @param archive an archive file such as a WAR or EAR -82 * @param extractTo a directory to extract the contents to -83 * @param engine the scanning engine -84 * @throws ExtractionException thrown if there is an error extracting the files -85 */ -86 public static void extractFiles(File archive, File extractTo, Engine engine) throws ExtractionException { -87 if (archive == null || extractTo == null) { -88 return; -89 } -90 -91 FileInputStream fis = null; -92 ZipInputStream zis = null; -93 -94 try { -95 fis = new FileInputStream(archive); -96 } catch (FileNotFoundException ex) { -97 LOGGER.log(Level.FINE, null, ex); -98 throw new ExtractionException("Archive file was not found.", ex); -99 } -100 zis = new ZipInputStream(new BufferedInputStream(fis)); -101 ZipEntry entry; -102 try { -103 while ((entry = zis.getNextEntry()) != null) { -104 if (entry.isDirectory()) { -105 final File d = new File(extractTo, entry.getName()); -106 if (!d.exists() && !d.mkdirs()) { -107 final String msg = String.format("Unable to create '%s'.", d.getAbsolutePath()); -108 throw new ExtractionException(msg); -109 } -110 } else { -111 final File file = new File(extractTo, entry.getName()); -112 final String ext = getFileExtension(file.getName()); -113 if (engine == null || engine.supportsExtension(ext)) { -114 BufferedOutputStream bos = null; -115 FileOutputStream fos; -116 try { -117 fos = new FileOutputStream(file); -118 bos = new BufferedOutputStream(fos, BUFFER_SIZE); -119 transferUsingBuffer(zis, bos); -120 } catch (FileNotFoundException ex) { -121 LOGGER.log(Level.FINE, null, ex); -122 final String msg = String.format("Unable to find file '%s'.", file.getName()); -123 throw new ExtractionException(msg, ex); -124 } catch (IOException ex) { -125 LOGGER.log(Level.FINE, null, ex); -126 final String msg = String.format("IO Exception while parsing file '%s'.", file.getName()); -127 throw new ExtractionException(msg, ex); -128 } finally { -129 closeStream(bos); -130 } -131 } -132 } -133 } -134 } catch (IOException ex) { -135 final String msg = String.format("Exception reading archive '%s'.", archive.getName()); -136 LOGGER.log(Level.FINE, msg, ex); -137 throw new ExtractionException(msg, ex); -138 } finally { -139 closeStream(zis); -140 } -141 } -142 -143 /** -144 * Extracts the contents of an archive into the specified directory. -145 * -146 * @param archive an archive file such as a WAR or EAR -147 * @param destination a directory to extract the contents to -148 * @param filter determines which files get extracted -149 * @throws ExtractionException thrown if the archive is not found -150 */ -151 public static void extractFilesUsingFilter(File archive, File destination, -152 FilenameFilter filter) throws ExtractionException { -153 if (archive == null || destination == null) { -154 return; -155 } -156 -157 FileInputStream fis = null; -158 try { -159 fis = new FileInputStream(archive); -160 } catch (FileNotFoundException ex) { -161 LOGGER.log(Level.FINE, null, ex); -162 throw new ExtractionException("Archive file was not found.", ex); -163 } -164 try { -165 extractArchive(new ZipArchiveInputStream(new BufferedInputStream( -166 fis)), destination, filter); -167 } catch (ArchiveExtractionException ex) { -168 final String msg = String.format( -169 "Exception extracting archive '%s'.", archive.getName()); -170 LOGGER.log(Level.WARNING, msg); -171 LOGGER.log(Level.FINE, null, ex); -172 } finally { -173 try { -174 fis.close(); -175 } catch (IOException ex) { -176 LOGGER.log(Level.FINE, null, ex); -177 } -178 } -179 } -180 -181 /** -182 * Extracts files from an archive. -183 * -184 * @param input the archive to extract files from -185 * @param destination the location to write the files too -186 * @param filter determines which files get extracted -187 * @throws ArchiveExtractionException thrown if there is an exception extracting files from the archive -188 */ -189 private static void extractArchive(ArchiveInputStream input, -190 File destination, FilenameFilter filter) -191 throws ArchiveExtractionException { -192 ArchiveEntry entry; -193 try { -194 while ((entry = input.getNextEntry()) != null) { -195 if (entry.isDirectory()) { -196 final File dir = new File(destination, entry.getName()); -197 if (!dir.exists()) { -198 if (!dir.mkdirs()) { -199 final String msg = String.format( -200 "Unable to create directory '%s'.", -201 dir.getAbsolutePath()); -202 throw new AnalysisException(msg); -203 } -204 } -205 } else { -206 extractFile(input, destination, filter, entry); -207 } -208 } -209 } catch (IOException ex) { -210 throw new ArchiveExtractionException(ex); -211 } catch (Throwable ex) { -212 throw new ArchiveExtractionException(ex); -213 } finally { -214 closeStream(input); -215 } -216 } -217 -218 /** -219 * Extracts a file from an archive (input stream) and correctly builds the directory structure. -220 * -221 * @param input the archive input stream -222 * @param destination where to write the file -223 * @param filter the file filter to apply to the files being extracted -224 * @param entry the entry from the archive to extract -225 * @throws ExtractionException thrown if there is an error reading from the archive stream -226 */ -227 private static void extractFile(ArchiveInputStream input, File destination, -228 FilenameFilter filter, ArchiveEntry entry) throws ExtractionException { -229 final File file = new File(destination, entry.getName()); -230 if (filter.accept(file.getParentFile(), file.getName())) { -231 final String extracting = String.format("Extracting '%s'", -232 file.getPath()); -233 LOGGER.fine(extracting); -234 BufferedOutputStream bos = null; -235 FileOutputStream fos = null; -236 try { -237 createParentFile(file); -238 fos = new FileOutputStream(file); -239 bos = new BufferedOutputStream(fos, BUFFER_SIZE); -240 transferUsingBuffer(input, bos); -241 } catch (FileNotFoundException ex) { -242 LOGGER.log(Level.FINE, null, ex); -243 final String msg = String.format("Unable to find file '%s'.", -244 file.getName()); +20 import java.io.BufferedInputStream; +21 import java.io.BufferedOutputStream; +22 import java.io.Closeable; +23 import java.io.File; +24 import java.io.FileInputStream; +25 import java.io.FileNotFoundException; +26 import java.io.FileOutputStream; +27 import java.io.FilenameFilter; +28 import java.io.IOException; +29 import java.io.InputStream; +30 import java.util.zip.ZipEntry; +31 import java.util.zip.ZipInputStream; +32 +33 import org.apache.commons.compress.archivers.ArchiveEntry; +34 import org.apache.commons.compress.archivers.ArchiveInputStream; +35 import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream; +36 import org.owasp.dependencycheck.Engine; +37 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; +38 import org.owasp.dependencycheck.analyzer.exception.ArchiveExtractionException; +39 import org.slf4j.Logger; +40 import org.slf4j.LoggerFactory; +41 +42 /** +43 * Set of utilities to extract files from archives. +44 * +45 * @author Jeremy Long +46 */ +47 public final class ExtractionUtil { +48 +49 /** +50 * The logger. +51 */ +52 private static final Logger LOGGER = LoggerFactory.getLogger(ExtractionUtil.class); +53 /** +54 * The buffer size to use when extracting files from the archive. +55 */ +56 private static final int BUFFER_SIZE = 4096; +57 +58 /** +59 * Private constructor for a utility class. +60 */ +61 private ExtractionUtil() { +62 } +63 +64 /** +65 * Extracts the contents of an archive into the specified directory. +66 * +67 * @param archive an archive file such as a WAR or EAR +68 * @param extractTo a directory to extract the contents to +69 * @throws ExtractionException thrown if an exception occurs while extracting the files +70 */ +71 public static void extractFiles(File archive, File extractTo) throws ExtractionException { +72 extractFiles(archive, extractTo, null); +73 } +74 +75 /** +76 * Extracts the contents of an archive into the specified directory. The files are only extracted if they are supported by the +77 * analyzers loaded into the specified engine. If the engine is specified as null then all files are extracted. +78 * +79 * @param archive an archive file such as a WAR or EAR +80 * @param extractTo a directory to extract the contents to +81 * @param engine the scanning engine +82 * @throws ExtractionException thrown if there is an error extracting the files +83 */ +84 public static void extractFiles(File archive, File extractTo, Engine engine) throws ExtractionException { +85 if (archive == null || extractTo == null) { +86 return; +87 } +88 +89 FileInputStream fis = null; +90 ZipInputStream zis = null; +91 +92 try { +93 fis = new FileInputStream(archive); +94 } catch (FileNotFoundException ex) { +95 LOGGER.debug("", ex); +96 throw new ExtractionException("Archive file was not found.", ex); +97 } +98 zis = new ZipInputStream(new BufferedInputStream(fis)); +99 ZipEntry entry; +100 try { +101 while ((entry = zis.getNextEntry()) != null) { +102 if (entry.isDirectory()) { +103 final File d = new File(extractTo, entry.getName()); +104 if (!d.exists() && !d.mkdirs()) { +105 final String msg = String.format("Unable to create '%s'.", d.getAbsolutePath()); +106 throw new ExtractionException(msg); +107 } +108 } else { +109 final File file = new File(extractTo, entry.getName()); +110 if (engine == null || engine.accept(file)) { +111 BufferedOutputStream bos = null; +112 FileOutputStream fos; +113 try { +114 fos = new FileOutputStream(file); +115 bos = new BufferedOutputStream(fos, BUFFER_SIZE); +116 transferUsingBuffer(zis, bos); +117 } catch (FileNotFoundException ex) { +118 LOGGER.debug("", ex); +119 final String msg = String.format("Unable to find file '%s'.", file.getName()); +120 throw new ExtractionException(msg, ex); +121 } catch (IOException ex) { +122 LOGGER.debug("", ex); +123 final String msg = String.format("IO Exception while parsing file '%s'.", file.getName()); +124 throw new ExtractionException(msg, ex); +125 } finally { +126 closeStream(bos); +127 } +128 } +129 } +130 } +131 } catch (IOException ex) { +132 final String msg = String.format("Exception reading archive '%s'.", archive.getName()); +133 LOGGER.debug("", ex); +134 throw new ExtractionException(msg, ex); +135 } finally { +136 closeStream(zis); +137 } +138 } +139 +140 /** +141 * Extracts the contents of an archive into the specified directory. +142 * +143 * @param archive an archive file such as a WAR or EAR +144 * @param destination a directory to extract the contents to +145 * @param filter determines which files get extracted +146 * @throws ExtractionException thrown if the archive is not found +147 */ +148 public static void extractFilesUsingFilter(File archive, File destination, +149 FilenameFilter filter) throws ExtractionException { +150 if (archive == null || destination == null) { +151 return; +152 } +153 +154 FileInputStream fis = null; +155 try { +156 fis = new FileInputStream(archive); +157 } catch (FileNotFoundException ex) { +158 LOGGER.debug("", ex); +159 throw new ExtractionException("Archive file was not found.", ex); +160 } +161 try { +162 extractArchive(new ZipArchiveInputStream(new BufferedInputStream( +163 fis)), destination, filter); +164 } catch (ArchiveExtractionException ex) { +165 LOGGER.warn("Exception extracting archive '{}'.", archive.getName()); +166 LOGGER.debug("", ex); +167 } finally { +168 try { +169 fis.close(); +170 } catch (IOException ex) { +171 LOGGER.debug("", ex); +172 } +173 } +174 } +175 +176 /** +177 * Extracts files from an archive. +178 * +179 * @param input the archive to extract files from +180 * @param destination the location to write the files too +181 * @param filter determines which files get extracted +182 * @throws ArchiveExtractionException thrown if there is an exception extracting files from the archive +183 */ +184 private static void extractArchive(ArchiveInputStream input, +185 File destination, FilenameFilter filter) +186 throws ArchiveExtractionException { +187 ArchiveEntry entry; +188 try { +189 while ((entry = input.getNextEntry()) != null) { +190 if (entry.isDirectory()) { +191 final File dir = new File(destination, entry.getName()); +192 if (!dir.exists()) { +193 if (!dir.mkdirs()) { +194 final String msg = String.format( +195 "Unable to create directory '%s'.", +196 dir.getAbsolutePath()); +197 throw new AnalysisException(msg); +198 } +199 } +200 } else { +201 extractFile(input, destination, filter, entry); +202 } +203 } +204 } catch (IOException ex) { +205 throw new ArchiveExtractionException(ex); +206 } catch (Throwable ex) { +207 throw new ArchiveExtractionException(ex); +208 } finally { +209 closeStream(input); +210 } +211 } +212 +213 /** +214 * Extracts a file from an archive (input stream) and correctly builds the directory structure. +215 * +216 * @param input the archive input stream +217 * @param destination where to write the file +218 * @param filter the file filter to apply to the files being extracted +219 * @param entry the entry from the archive to extract +220 * @throws ExtractionException thrown if there is an error reading from the archive stream +221 */ +222 private static void extractFile(ArchiveInputStream input, File destination, +223 FilenameFilter filter, ArchiveEntry entry) throws ExtractionException { +224 final File file = new File(destination, entry.getName()); +225 if (filter.accept(file.getParentFile(), file.getName())) { +226 LOGGER.debug("Extracting '{}'", +227 file.getPath()); +228 BufferedOutputStream bos = null; +229 FileOutputStream fos = null; +230 try { +231 createParentFile(file); +232 fos = new FileOutputStream(file); +233 bos = new BufferedOutputStream(fos, BUFFER_SIZE); +234 transferUsingBuffer(input, bos); +235 } catch (FileNotFoundException ex) { +236 LOGGER.debug("", ex); +237 final String msg = String.format("Unable to find file '%s'.", +238 file.getName()); +239 throw new ExtractionException(msg, ex); +240 } catch (IOException ex) { +241 LOGGER.debug("", ex); +242 final String msg = String +243 .format("IO Exception while parsing file '%s'.", +244 file.getName()); 245 throw new ExtractionException(msg, ex); -246 } catch (IOException ex) { -247 LOGGER.log(Level.FINE, null, ex); -248 final String msg = String -249 .format("IO Exception while parsing file '%s'.", -250 file.getName()); -251 throw new ExtractionException(msg, ex); -252 } finally { -253 closeStream(bos); -254 closeStream(fos); -255 } -256 } -257 } -258 -259 /** -260 * Transfers data from one stream to another using a buffer. -261 * -262 * @param input the input stream -263 * @param bos the output stream -264 * @throws IOException thrown if there is an error reading/writing to the streams -265 */ -266 private static void transferUsingBuffer(InputStream input, -267 BufferedOutputStream bos) throws IOException { -268 int count; -269 final byte[] data = new byte[BUFFER_SIZE]; -270 while ((count = input.read(data, 0, BUFFER_SIZE)) != -1) { -271 bos.write(data, 0, count); -272 } -273 bos.flush(); -274 } -275 -276 /** -277 * Closes the stream. -278 * -279 * @param stream the stream to close -280 */ -281 private static void closeStream(Closeable stream) { -282 if (stream != null) { -283 try { -284 stream.close(); -285 } catch (IOException ex) { -286 LOGGER.log(Level.FINEST, null, ex); -287 } -288 } -289 } -290 -291 /** -292 * Ensures the parent path is correctly created on disk so that the file can be extracted to the correct location. -293 * -294 * @param file the file path -295 * @throws ExtractionException thrown if the parent paths could not be created -296 */ -297 private static void createParentFile(final File file) -298 throws ExtractionException { -299 final File parent = file.getParentFile(); -300 if (!parent.isDirectory()) { -301 if (!parent.mkdirs()) { -302 final String msg = String.format( -303 "Unable to build directory '%s'.", -304 parent.getAbsolutePath()); -305 throw new ExtractionException(msg); -306 } -307 } -308 } -309 -310 } +246 } finally { +247 closeStream(bos); +248 closeStream(fos); +249 } +250 } +251 } +252 +253 /** +254 * Transfers data from one stream to another using a buffer. +255 * +256 * @param input the input stream +257 * @param bos the output stream +258 * @throws IOException thrown if there is an error reading/writing to the streams +259 */ +260 private static void transferUsingBuffer(InputStream input, +261 BufferedOutputStream bos) throws IOException { +262 int count; +263 final byte[] data = new byte[BUFFER_SIZE]; +264 while ((count = input.read(data, 0, BUFFER_SIZE)) != -1) { +265 bos.write(data, 0, count); +266 } +267 bos.flush(); +268 } +269 +270 /** +271 * Closes the stream. +272 * +273 * @param stream the stream to close +274 */ +275 private static void closeStream(Closeable stream) { +276 if (stream != null) { +277 try { +278 stream.close(); +279 } catch (IOException ex) { +280 LOGGER.trace("", ex); +281 } +282 } +283 } +284 +285 /** +286 * Ensures the parent path is correctly created on disk so that the file can be extracted to the correct location. +287 * +288 * @param file the file path +289 * @throws ExtractionException thrown if the parent paths could not be created +290 */ +291 private static void createParentFile(final File file) +292 throws ExtractionException { +293 final File parent = file.getParentFile(); +294 if (!parent.isDirectory()) { +295 if (!parent.mkdirs()) { +296 final String msg = String.format( +297 "Unable to build directory '%s'.", +298 parent.getAbsolutePath()); +299 throw new ExtractionException(msg); +300 } +301 } +302 } +303 }
    diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/utils/FileFilterBuilder.html b/dependency-check-core/xref/org/owasp/dependencycheck/utils/FileFilterBuilder.html new file mode 100644 index 000000000..26c1a00e1 --- /dev/null +++ b/dependency-check-core/xref/org/owasp/dependencycheck/utils/FileFilterBuilder.html @@ -0,0 +1,151 @@ + + + +FileFilterBuilder 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) 2015 Institute for Defense Analyses. All Rights Reserved.
    +17   */
    +18  package org.owasp.dependencycheck.utils;
    +19  
    +20  import org.apache.commons.io.IOCase;
    +21  import org.apache.commons.io.filefilter.IOFileFilter;
    +22  import org.apache.commons.io.filefilter.NameFileFilter;
    +23  import org.apache.commons.io.filefilter.OrFileFilter;
    +24  import org.apache.commons.io.filefilter.SuffixFileFilter;
    +25  
    +26  import java.io.FileFilter;
    +27  import java.util.ArrayList;
    +28  import java.util.Arrays;
    +29  import java.util.HashSet;
    +30  import java.util.List;
    +31  import java.util.Set;
    +32  
    +33  /**
    +34   * <p>
    +35   * Utility class for building useful {@link FileFilter} instances for
    +36   * {@link org.owasp.dependencycheck.analyzer.AbstractFileTypeAnalyzer} implementations. The built filter uses {@link OrFileFilter}
    +37   * to logically OR the given filter conditions. Example usage:</p>
    +38   *
    +39   * <pre>
    +40   *     FileFilter filter = FileFilterBuilder.newInstance().addExtensions("jar", "war").build();
    +41   * </pre>
    +42   *
    +43   * @author Dale Visser <dvisser@ida.org>
    +44   * @see <a href="https://en.wikipedia.org/wiki/Builder_pattern">Builder pattern</a>
    +45   */
    +46  public class FileFilterBuilder {
    +47  
    +48      /**
    +49       * A set of filenames to filter.
    +50       */
    +51      private final Set<String> filenames = new HashSet<String>();
    +52      /**
    +53       * A set of extensions to filter.
    +54       */
    +55      private final Set<String> extensions = new HashSet<String>();
    +56      /**
    +57       * An array list of file filters.
    +58       */
    +59      private final List<IOFileFilter> fileFilters = new ArrayList<IOFileFilter>();
    +60  
    +61      /**
    +62       * Create a new instance and return it. This method is for convenience in using the builder pattern within a single statement.
    +63       *
    +64       * @return a new builder instance
    +65       */
    +66      public static FileFilterBuilder newInstance() {
    +67          return new FileFilterBuilder();
    +68      }
    +69  
    +70      /**
    +71       * Add to the set of filenames to accept for analysis. Case-sensitivity is assumed.
    +72       *
    +73       * @param names one or more filenames to accept for analysis
    +74       * @return this builder
    +75       */
    +76      public FileFilterBuilder addFilenames(String... names) {
    +77          filenames.addAll(Arrays.asList(names));
    +78          return this;
    +79      }
    +80  
    +81      /**
    +82       * Add to the set of file extensions to accept for analysis. Case-insensitivity is assumed.
    +83       *
    +84       * @param extensions one or more file extensions to accept for analysis
    +85       * @return this builder
    +86       */
    +87      public FileFilterBuilder addExtensions(String... extensions) {
    +88          return this.addExtensions(Arrays.asList(extensions));
    +89      }
    +90  
    +91      /**
    +92       * Add to the set of file extensions to accept for analysis. Case-insensitivity is assumed.
    +93       *
    +94       * @param extensions one or more file extensions to accept for analysis
    +95       * @return this builder
    +96       */
    +97      public FileFilterBuilder addExtensions(Iterable<String> extensions) {
    +98          for (String extension : extensions) {
    +99              // Ultimately, SuffixFileFilter will be used, and the "." needs to be explicit.
    +100             this.extensions.add(extension.startsWith(".") ? extension : "." + extension);
    +101         }
    +102         return this;
    +103     }
    +104 
    +105     /**
    +106      * Add to a list of {@link IOFileFilter} instances to consult for whether to accept a file for analysis.
    +107      *
    +108      * @param filters one or more file filters to consult for whether to accept for analysis
    +109      * @return this builder
    +110      */
    +111     public FileFilterBuilder addFileFilters(IOFileFilter... filters) {
    +112         fileFilters.addAll(Arrays.asList(filters));
    +113         return this;
    +114     }
    +115 
    +116     /**
    +117      * Builds the filter and returns it.
    +118      *
    +119      * @return a filter that is the logical OR of all the conditions provided by the add... methods
    +120      * @throws IllegalStateException if no add... method has been called with one or more arguments
    +121      */
    +122     public FileFilter build() {
    +123         if (filenames.isEmpty() && extensions.isEmpty() && fileFilters.isEmpty()) {
    +124             throw new IllegalStateException("May only be invoked after at least one add... method has been invoked.");
    +125         }
    +126         final OrFileFilter filter = new OrFileFilter();
    +127         if (!filenames.isEmpty()) {
    +128             filter.addFileFilter(new NameFileFilter(new ArrayList<String>(filenames)));
    +129         }
    +130         if (!extensions.isEmpty()) {
    +131             filter.addFileFilter(new SuffixFileFilter(new ArrayList<String>(extensions), IOCase.INSENSITIVE));
    +132         }
    +133         for (IOFileFilter iof : fileFilters) {
    +134             filter.addFileFilter(iof);
    +135         }
    +136         return filter;
    +137     }
    +138 }
    +
    +
    + + + 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 b161811ee..934ab76a0 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.2.11 Reference Package org.owasp.dependencycheck.utils + Dependency-Check Core 1.3.0 Reference Package org.owasp.dependencycheck.utils @@ -29,6 +29,9 @@
  • ExtractionUtil +
  • +
  • + FileFilterBuilder
  • Filter 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 13ee33c80..b167fa38d 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.2.11 Reference Package org.owasp.dependencycheck.utils + Dependency-Check Core 1.3.0 Reference Package org.owasp.dependencycheck.utils @@ -59,6 +59,11 @@ ExtractionUtil + + + + FileFilterBuilder + diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/xml/pom/PomParser.html b/dependency-check-core/xref/org/owasp/dependencycheck/xml/pom/PomParser.html index 827087ab7..c2020aa23 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/xml/pom/PomParser.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/xml/pom/PomParser.html @@ -32,92 +32,93 @@ 24 import java.io.InputStream; 25 import java.io.InputStreamReader; 26 import java.io.Reader; -27 import java.util.logging.Level; -28 import java.util.logging.Logger; -29 import javax.xml.parsers.ParserConfigurationException; -30 import javax.xml.parsers.SAXParser; -31 import javax.xml.parsers.SAXParserFactory; -32 import org.xml.sax.InputSource; -33 import org.xml.sax.SAXException; -34 import org.xml.sax.XMLReader; -35 -36 /** -37 * A parser for pom.xml files. -38 * -39 * @author Jeremy Long -40 */ -41 public class PomParser { -42 -43 /** -44 * The logger. -45 */ -46 private static final Logger LOGGER = Logger.getLogger(PomParser.class.getName()); -47 -48 /** -49 * Parses the given xml file and returns a Model object containing only the fields dependency-check requires. -50 * -51 * @param file a pom.xml -52 * @return a Model object containing only the fields dependency-check requires -53 * @throws PomParseException thrown if the xml file cannot be parsed -54 */ -55 public Model parse(File file) throws PomParseException { -56 FileInputStream fis = null; -57 try { -58 fis = new FileInputStream(file); -59 return parse(fis); -60 } catch (IOException ex) { -61 LOGGER.log(Level.FINE, null, ex); -62 throw new PomParseException(ex); -63 } finally { -64 if (fis != null) { -65 try { -66 fis.close(); -67 } catch (IOException ex) { -68 LOGGER.log(Level.FINE, "Unable to close stream", ex); -69 } -70 } -71 } -72 } -73 -74 /** -75 * Parses the given XML file and returns a Model object containing only the fields dependency-check requires. -76 * -77 * @param inputStream an InputStream containing suppression rues -78 * @return a list of suppression rules -79 * @throws PomParseException if the XML cannot be parsed -80 */ -81 public Model parse(InputStream inputStream) throws PomParseException { -82 try { -83 final PomHandler handler = new PomHandler(); -84 final SAXParserFactory factory = SAXParserFactory.newInstance(); -85 // factory.setNamespaceAware(true); -86 // factory.setValidating(true); -87 final SAXParser saxParser = factory.newSAXParser(); -88 final XMLReader xmlReader = saxParser.getXMLReader(); -89 xmlReader.setContentHandler(handler); -90 -91 final Reader reader = new InputStreamReader(inputStream, "UTF-8"); -92 final InputSource in = new InputSource(reader); -93 //in.setEncoding("UTF-8"); -94 -95 xmlReader.parse(in); -96 -97 return handler.getModel(); -98 } catch (ParserConfigurationException ex) { -99 LOGGER.log(Level.FINE, null, ex); -100 throw new PomParseException(ex); -101 } catch (SAXException ex) { -102 LOGGER.log(Level.FINE, null, ex); -103 throw new PomParseException(ex); -104 } catch (FileNotFoundException ex) { -105 LOGGER.log(Level.FINE, null, ex); -106 throw new PomParseException(ex); -107 } catch (IOException ex) { -108 LOGGER.log(Level.FINE, null, ex); -109 throw new PomParseException(ex); -110 } -111 } -112 } +27 import javax.xml.parsers.ParserConfigurationException; +28 import javax.xml.parsers.SAXParser; +29 import javax.xml.parsers.SAXParserFactory; +30 +31 import org.slf4j.Logger; +32 import org.slf4j.LoggerFactory; +33 import org.xml.sax.InputSource; +34 import org.xml.sax.SAXException; +35 import org.xml.sax.XMLReader; +36 +37 /** +38 * A parser for pom.xml files. +39 * +40 * @author Jeremy Long +41 */ +42 public class PomParser { +43 +44 /** +45 * The logger. +46 */ +47 private static final Logger LOGGER = LoggerFactory.getLogger(PomParser.class); +48 +49 /** +50 * Parses the given xml file and returns a Model object containing only the fields dependency-check requires. +51 * +52 * @param file a pom.xml +53 * @return a Model object containing only the fields dependency-check requires +54 * @throws PomParseException thrown if the xml file cannot be parsed +55 */ +56 public Model parse(File file) throws PomParseException { +57 FileInputStream fis = null; +58 try { +59 fis = new FileInputStream(file); +60 return parse(fis); +61 } catch (IOException ex) { +62 LOGGER.debug("", ex); +63 throw new PomParseException(ex); +64 } finally { +65 if (fis != null) { +66 try { +67 fis.close(); +68 } catch (IOException ex) { +69 LOGGER.debug("Unable to close stream", ex); +70 } +71 } +72 } +73 } +74 +75 /** +76 * Parses the given XML file and returns a Model object containing only the fields dependency-check requires. +77 * +78 * @param inputStream an InputStream containing suppression rues +79 * @return a list of suppression rules +80 * @throws PomParseException if the XML cannot be parsed +81 */ +82 public Model parse(InputStream inputStream) throws PomParseException { +83 try { +84 final PomHandler handler = new PomHandler(); +85 final SAXParserFactory factory = SAXParserFactory.newInstance(); +86 // factory.setNamespaceAware(true); +87 // factory.setValidating(true); +88 final SAXParser saxParser = factory.newSAXParser(); +89 final XMLReader xmlReader = saxParser.getXMLReader(); +90 xmlReader.setContentHandler(handler); +91 +92 final Reader reader = new InputStreamReader(inputStream, "UTF-8"); +93 final InputSource in = new InputSource(reader); +94 //in.setEncoding("UTF-8"); +95 +96 xmlReader.parse(in); +97 +98 return handler.getModel(); +99 } catch (ParserConfigurationException ex) { +100 LOGGER.debug("", ex); +101 throw new PomParseException(ex); +102 } catch (SAXException ex) { +103 LOGGER.debug("", ex); +104 throw new PomParseException(ex); +105 } catch (FileNotFoundException ex) { +106 LOGGER.debug("", ex); +107 throw new PomParseException(ex); +108 } catch (IOException ex) { +109 LOGGER.debug("", ex); +110 throw new PomParseException(ex); +111 } +112 } +113 }
    diff --git a/dependency-check-core/xref/org/owasp/dependencycheck/xml/pom/PomUtils.html b/dependency-check-core/xref/org/owasp/dependencycheck/xml/pom/PomUtils.html index b1d2a46ef..88c18a6ca 100644 --- a/dependency-check-core/xref/org/owasp/dependencycheck/xml/pom/PomUtils.html +++ b/dependency-check-core/xref/org/owasp/dependencycheck/xml/pom/PomUtils.html @@ -28,12 +28,12 @@ 20 import java.io.File; 21 import java.io.IOException; 22 import java.util.jar.JarFile; -23 import java.util.logging.Level; -24 import java.util.logging.Logger; -25 import java.util.zip.ZipEntry; -26 import org.owasp.dependencycheck.analyzer.JarAnalyzer; -27 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; -28 import org.owasp.dependencycheck.dependency.Dependency; +23 import java.util.zip.ZipEntry; +24 import org.owasp.dependencycheck.analyzer.JarAnalyzer; +25 import org.owasp.dependencycheck.analyzer.exception.AnalysisException; +26 import org.owasp.dependencycheck.dependency.Dependency; +27 import org.slf4j.Logger; +28 import org.slf4j.LoggerFactory; 29 30 /** 31 * @@ -49,89 +49,81 @@ 41 /** 42 * The logger. 43 */ -44 private static final Logger LOGGER = Logger.getLogger(PomUtils.class.getName()); +44 private static final Logger LOGGER = LoggerFactory.getLogger(PomUtils.class); 45 46 /** 47 * Reads in the specified POM and converts it to a Model. 48 * 49 * @param file the pom.xml file 50 * @return returns a -51 * @throws AnalysisException is thrown if there is an exception extracting or parsing the POM -52 * {@link org.owasp.dependencycheck.jaxb.pom.generated.Model} object -53 */ -54 public static Model readPom(File file) throws AnalysisException { -55 Model model = null; -56 try { -57 final PomParser parser = new PomParser(); -58 model = parser.parse(file); -59 } catch (PomParseException ex) { -60 final String msg = String.format("Unable to parse pom '%s'", file.getPath()); -61 LOGGER.log(Level.WARNING, msg); -62 LOGGER.log(Level.FINE, "", ex); -63 throw new AnalysisException(ex); -64 } catch (IOException ex) { -65 final String msg = String.format("Unable to parse pom '%s'(IO Exception)", file.getPath()); -66 LOGGER.log(Level.WARNING, msg); -67 LOGGER.log(Level.FINE, "", ex); -68 throw new AnalysisException(ex); -69 } catch (Throwable ex) { -70 final String msg = String.format("Unexpected error during parsing of the pom '%s'", file.getPath()); -71 LOGGER.log(Level.WARNING, msg); -72 LOGGER.log(Level.FINE, "", ex); -73 throw new AnalysisException(ex); -74 } -75 return model; -76 } -77 -78 /** -79 * Retrieves the specified POM from a jar file and converts it to a Model. -80 * -81 * @param path the path to the pom.xml file within the jar file -82 * @param jar the jar file to extract the pom from -83 * @return returns a -84 * @throws AnalysisException is thrown if there is an exception extracting or parsing the POM -85 * {@link org.owasp.dependencycheck.jaxb.pom.generated.Model} object -86 */ -87 public static Model readPom(String path, JarFile jar) throws AnalysisException { -88 final ZipEntry entry = jar.getEntry(path); -89 Model model = null; -90 if (entry != null) { //should never be null -91 try { -92 final PomParser parser = new PomParser(); -93 model = parser.parse(jar.getInputStream(entry)); -94 LOGGER.fine(String.format("Read POM %s", path)); -95 } catch (SecurityException ex) { -96 final String msg = String.format("Unable to parse pom '%s' in jar '%s'; invalid signature", path, jar.getName()); -97 LOGGER.log(Level.WARNING, msg); -98 LOGGER.log(Level.FINE, null, ex); -99 throw new AnalysisException(ex); -100 } catch (IOException ex) { -101 final String msg = String.format("Unable to parse pom '%s' in jar '%s' (IO Exception)", path, jar.getName()); -102 LOGGER.log(Level.WARNING, msg); -103 LOGGER.log(Level.FINE, "", ex); -104 throw new AnalysisException(ex); -105 } catch (Throwable ex) { -106 final String msg = String.format("Unexpected error during parsing of the pom '%s' in jar '%s'", path, jar.getName()); -107 LOGGER.log(Level.WARNING, msg); -108 LOGGER.log(Level.FINE, "", ex); -109 throw new AnalysisException(ex); -110 } -111 } -112 return model; -113 } -114 -115 /** -116 * Reads in the pom file and adds elements as evidence to the given dependency. -117 * -118 * @param dependency the dependency being analyzed -119 * @param pomFile the pom file to read -120 * @throws AnalysisException is thrown if there is an exception parsing the pom -121 */ -122 public static void analyzePOM(Dependency dependency, File pomFile) throws AnalysisException { -123 final Model pom = PomUtils.readPom(pomFile); -124 JarAnalyzer.setPomEvidence(dependency, pom, null); -125 } -126 } +51 * @throws AnalysisException is thrown if there is an exception extracting or parsing the POM {@link Model} object +52 */ +53 public static Model readPom(File file) throws AnalysisException { +54 Model model = null; +55 try { +56 final PomParser parser = new PomParser(); +57 model = parser.parse(file); +58 } catch (PomParseException ex) { +59 LOGGER.warn("Unable to parse pom '{}'", file.getPath()); +60 LOGGER.debug("", ex); +61 throw new AnalysisException(ex); +62 } catch (IOException ex) { +63 LOGGER.warn("Unable to parse pom '{}'(IO Exception)", file.getPath()); +64 LOGGER.debug("", ex); +65 throw new AnalysisException(ex); +66 } catch (Throwable ex) { +67 LOGGER.warn("Unexpected error during parsing of the pom '{}'", file.getPath()); +68 LOGGER.debug("", ex); +69 throw new AnalysisException(ex); +70 } +71 return model; +72 } +73 +74 /** +75 * Retrieves the specified POM from a jar file and converts it to a Model. +76 * +77 * @param path the path to the pom.xml file within the jar file +78 * @param jar the jar file to extract the pom from +79 * @return returns a +80 * @throws AnalysisException is thrown if there is an exception extracting or parsing the POM {@link Model} object +81 */ +82 public static Model readPom(String path, JarFile jar) throws AnalysisException { +83 final ZipEntry entry = jar.getEntry(path); +84 Model model = null; +85 if (entry != null) { //should never be null +86 try { +87 final PomParser parser = new PomParser(); +88 model = parser.parse(jar.getInputStream(entry)); +89 LOGGER.debug("Read POM {}", path); +90 } catch (SecurityException ex) { +91 LOGGER.warn("Unable to parse pom '{}' in jar '{}'; invalid signature", path, jar.getName()); +92 LOGGER.debug("", ex); +93 throw new AnalysisException(ex); +94 } catch (IOException ex) { +95 LOGGER.warn("Unable to parse pom '{}' in jar '{}' (IO Exception)", path, jar.getName()); +96 LOGGER.debug("", ex); +97 throw new AnalysisException(ex); +98 } catch (Throwable ex) { +99 LOGGER.warn("Unexpected error during parsing of the pom '{}' in jar '{}'", path, jar.getName()); +100 LOGGER.debug("", ex); +101 throw new AnalysisException(ex); +102 } +103 } +104 return model; +105 } +106 +107 /** +108 * Reads in the pom file and adds elements as evidence to the given dependency. +109 * +110 * @param dependency the dependency being analyzed +111 * @param pomFile the pom file to read +112 * @throws AnalysisException is thrown if there is an exception parsing the pom +113 */ +114 public static void analyzePOM(Dependency dependency, File pomFile) throws AnalysisException { +115 final Model pom = PomUtils.readPom(pomFile); +116 JarAnalyzer.setPomEvidence(dependency, pom, null); +117 } +118 }
    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 b83234d9a..343a2f615 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.2.11 Reference Package org.owasp.dependencycheck.xml.pom + Dependency-Check Core 1.3.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 f2cb2dc2f..23c9ad619 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.2.11 Reference Package org.owasp.dependencycheck.xml.pom + Dependency-Check Core 1.3.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 b60ebe49f..841c8ec1d 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.2.11 Reference + Dependency-Check Core 1.3.0 Reference @@ -50,15 +50,15 @@
  • org.owasp.dependencycheck.data.update +
  • +
  • + org.owasp.dependencycheck.data.update.cpe
  • org.owasp.dependencycheck.data.update.exception
  • - org.owasp.dependencycheck.data.update.task -
  • -
  • - org.owasp.dependencycheck.data.update.xml + org.owasp.dependencycheck.data.update.nvd
  • org.owasp.dependencycheck.dependency diff --git a/dependency-check-core/xref/overview-summary.html b/dependency-check-core/xref/overview-summary.html index 5fa97ca2f..eea9203cb 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.2.11 Reference + Dependency-Check Core 1.3.0 Reference @@ -24,7 +24,7 @@ -

    Dependency-Check Core 1.2.11 Reference

    +

    Dependency-Check Core 1.3.0 Reference

    @@ -92,6 +92,11 @@ + + + - - - diff --git a/dependency-check-gradle/.gradle/2.3/taskArtifacts/cache.properties b/dependency-check-gradle/.gradle/2.3/taskArtifacts/cache.properties new file mode 100644 index 000000000..aac5b7633 --- /dev/null +++ b/dependency-check-gradle/.gradle/2.3/taskArtifacts/cache.properties @@ -0,0 +1 @@ +#Sat Aug 01 06:53:03 EDT 2015 diff --git a/dependency-check-gradle/.gradle/2.3/taskArtifacts/cache.properties.lock b/dependency-check-gradle/.gradle/2.3/taskArtifacts/cache.properties.lock new file mode 100644 index 0000000000000000000000000000000000000000..14f60ce271a82f6109fb76bb60ef2c4111b6a133 GIT binary patch literal 17 VcmZS1vSM1XWyXz01~6b$001um1Q-AS literal 0 HcmV?d00001 diff --git a/dependency-check-gradle/.gradle/2.3/taskArtifacts/fileHashes.bin b/dependency-check-gradle/.gradle/2.3/taskArtifacts/fileHashes.bin new file mode 100644 index 0000000000000000000000000000000000000000..b7e92df0248948ab7802b75c57c0d91d36bd530f GIT binary patch literal 31277 zcmeI4c{~^08~4Xj_9#>+Tec!wC83Q%_I=5kJz27rREVTf5#lZ+Eh>eGl0>A0&?04v zvX`wQ%JR&aGcz&$oYYj>#8rWHw4Wj1wh^7DWOLwYR2{?38h2bGnLSf3rn}u zet!`Hb@N_QKl#nbu`O{w)Gf{tdSo2{xzkonvHUW$_jD!o*Y&^F278@>x|bJHFoY&3$0d>9AgnoXKXZ=s!jg?UM79#WnADvY_OGe$Hu9ZvbRkc?1Oxx<9 zzB`Q2FSs4{ymlng1?o@u%ZFJ*>x@$C{U%Xwn%6?>M zHPrnANxg_`N28;NKGb(f6Z$1-`-}OnXcs})&0a;f6M7rP`AH8>Jzo0lg)MJJAvX~yI>+K=*I}bj--4kNO zi2JQ2^lZK(=H($m8Bo`ZB6ah@m#o|>cX8c-(C=|eolH;8>xH`ZG^y{su5{z0(jKTg zEhh9lW5LVff!5!l9yCVkRv{x%v5%XfZkSH!`H^mxXT#|hLw(NzQXl)xnLjYb2X(7D zLN5^TEhj>ccz!8{{y$26gis zLVpx|vhI1xR%fU?JtXv!hM))RY%c_$?$Sx&K826385xJFaF2rZX2u23-nE>tuYOXVohpehFT_Nd&}&w@Yu^qH$%Xb_ zd4&GzvEDt#Fl+R!Gx&MGAocP6%VLJU$wA$kfzWFo^*{L1TfqZ$Lw7>2|7az|$svU2 zA9ou<{aMmOtMP`4q+tLc9FNdNnDc2L)1CG1=5vJMWG+}{j!og1Y7x>}LH{Z%s5 z%~A-xHBh}>(NlRl)a@P+dRw%rR+J1|8q{}>5c-$;;Hi;>E!It+9w2penLi>Zhg#PvZ!^22df-%&! z4v~7f&eKh5%RHbSNanq-!-C&?jZOTaZa}WPfo!g)P4~{=^TclRi7OkU$`T=Xgen{U&u=mUPPf*`S?#m;7((#wPL*k)sL)IJLW5>srKAxC@ zy5mRUI^Pq2>y0T-r$PMyIUh#1ZBjY;?tLTFHOcui`qJrb$}-L^P~YWDT<6!K`wye& zMx~&xt3&9MizI{7L^r*Ix-Ge1PrgsMqj!Gy2dF!f`D*60Y2Pb#OE#$cZ6U6MJpXT9 zN5NSes9RnmbUHPi{Gp*GrcgKdP3Vl{IevUIF6B_)vzgGDyeAryeq_|(dKanxeik2U z{AU8{L1aE>X4bm6uy_T&emzbR_RMWTECWrvR?yy=+)r7rmjCBE=qjo%DphEd5y~&z?R!&jbz<`tsi$+(T`KCD7ipfzWxD z_O|{)Hvp(xC6c=FZl>wZ>o=k9D^BRVHBtJ}HB0dPzu$|{`C=saWDPmhp}hfFx2!NM zm~xPk!}FC5sjuYU98&bW7_V>jl8Ec@iv~R0Z03sRnSjfr{vgshrz|50Uf-Xr+Xd(X zW*&Js<8_+PFkvqs`fQ!pt8I?Z-hrH-0!2fHi-+2Jpzgy(*b9otwX8im;sA9E3qlw2 zO3OTyT*(ggU1a`T74qIpJhP)0>PBRoMZ^_1oQ|_u0(E0@zYtN|a>87S;}_Je$$eQg zrt&d=_o5-FyU7uL#e{Y%*|0ss_hmC_QeT^~d_qG)5ZdqNBy@3~DD4~`wK8*==fh9!g!;h_!hZGO(&$W1-50oio6x1coh+-q*l-Ezy5C9t zw`H~GnTxGZ_agVBwfnOY-rr-u^RS~lVZS!h&tdoBz(i>8Y)9xaVlkf&-h7Vlclu<0 zklDOSu6qD^1MT&w7li`N3S3xQf`(u2^A4QPIbm#ZIwx(OYjo2X9L zc8Ohk1oZ${Qa4)HTGthb*C%e53Eh;>Nh2a$iVxbmFc7+#k@^>#+DUv}JEoJmW6NO3 zT4p?+`&&uFEk6W4{v{}9p z_eqp?wfy8xe?kIO?nmWZn-CdN>ZP&FY{CTq--}f!ZebClp8{erD z+W7SkRFn2K!(9Q>3xeTw_U041UEm%juS071ygCq1==O~>J>D@0K0lqw{b)~AC;#}L z6SVL;fdz!UvyyJs=;cX4sGF7&y35@S3I#pA`2N2CI-$FsF20f@FE0)4_38=T%}!pu zwtMn4ejW0D)2-`OdEI&huamuY5cYew_q?(G&|?Yh{mFW7Z_iMuZhtQRJjc|Kuy?=c z(&3onxe3}kk^9uX3(8S1%wOaAdAAl}zppgR;bnIKzE8O|lKPLG@p_|=@%_a%jnF;i zB-@#yXYl((cQT${$9w}k{|rY$zdpwZd#~_X@yauF_&N<-MCuvZ^zEk#tDwC;IUl@A zDo1IDW5b|sPu2ro4W$qNqxpo-H;XCaI^L->Zt`*CyP>^h3!(4#u1r%?EyDBgUUgD0 zN-WE0io^Ho05Tu?OYcZre%9X?UdPOZu=hVV8GI`6`**0Dkae1W;RpSa=lX+Cx3VMb z1C(SOONV&xK;1lu)MMCdm6=-uq3%cS%Yh%7mmI?D78f!v9aL0pR=~&}#lTAA$J@%tv580`n1= zkHCBc<|8m4f%yo`M_@hz^AVVjzc*9g?C zLy0x$Kj6)^@M7e2#vb3Bp>*+`x023`c_yRZjnQaJC_jSlt-Lp5??3Z*KhVH9@U^!P z_=khjHC5?gM*1(KXI%d5#viT&EVj+09{rC9vf>H$nw~NL77f*1MU6UV(Wgf$b#}}T zjbrK`qMX)2aaqXGWn-^x?@9@%Q{1hs;90%n6U}x%4d*rEB}+a6?7)WVVay%>73^yq zIkvtU3dZ@^iFYdGqb*ae{a7-;4%#Xd+rcG^VT>ly?x6nxea6zwiQYh}0TevfvHjF)~ib$6pUw4*g4o1&} zy*iar?$xGXlEqG|PV)$mVqLJug|nZ7f9rsGe*A~nuXCcpqD|A0K-@d3MLT~(0Mv0HPyfSC3l|V zO6fTm!t@kiQqMK@sGX})4K0a#ujcBj)K&RzZG9o&4k#pY0DA=S-35*oock|RxwuT# z>q72RZYmp+qW5{1f0*mf7JFU)YF*|vN;Bo}amJvYk4L7q;1_kZA#&5rWr-K zzsnU_fci&}C=QqBRIZvc;(XZe9n#li#3MG}nvR0p+EQST(4~!l)4q^yMN0SFR%+c3 z5`5d$c_TfEMywO8AJm;FT&{>d_7O&d_pg&wcT*FqKP=}J;0i7bUc+(v_QV{Hw(&P` zr!1hvL2tHtaLdi;@R*sgTj_q_nQWtN<_2BtllA_*mq2srPUv)+#4^x&{MRo zV_|Il{TVyU!OZ*{6+|T;G;`qr#|4yT?qoxJua)UfZE(FR+t;@Z{hV<&wh3Lo2*S0{ zi@I$od?>jRsk!Vw(v{F#DOgMr)mwz*7?XU6+7IF~VwjY=y zG>8s3WoAZuQCs<|u6Rt@^%G0UwHMW5jK?3(;Sf$VwrB-$r+$LUJ?U7sdZodAzO&K8 zcT6^XT8VLD0`|ZjL87t!hhhJgaVmGU(oXf~xY5#V-q@M~&p339XD`=76@b=TBzTX? z<(l`4JYdfZU!-_*c#-NSFnDM*(_s>0oy5Mpw0j!%ippL5DER1$+5t%xC!f>_t_@?5 zyCewwAV@J<@*s#ypsp~+{jI1Bm#f7JD#VtE=T(HvSPS;e#SUQ~i0e9i?WSN>PVo;U zJzp2tamz5=iOk+Q2cwI`a-fFl=3f*{<9rUY+YcW1;TJ9j-OR@5=h&cgL?gS=!9u^hNlsp)E`auIx&Mz8Cx2nx}a-{BB+p=}O_lw(sYkh4I5(oDmy zLdDge)V)N%6el`QoTW6g3Jd0gEnN~6Y~QiCw#b&!uaD##LMFso(N6?twUX9rFKA`d zbO|lBmF3GGxX5@1A5;6!Gu2w44gKVB7Ka4T1CCC=Dvinw7DYq`1u1W0+@s5u;gE&~ zeKxn`DBv=i+qY1;6b8Da)(O`Bby4KCXXbxQg7`?E$2L)T*e1@mKkdbcOq~}KwZ#?@P47n2y zu->Rga5JAZqhGg3CX6rradB6etc?AP(C4|F>LlQ*T)6ru?#zzyb9emSlBQ&MJ;EY+ z4f@w#W_6BnQW0R?5gpel7~|Gl>D#NnGpz9Nm0%4}K_~Dm3^|5<^=s0!=?I3+YGsep zy4t!%qg5v)O{bG8IneTV7Du~$8*o=unps3~=hpaj^|G5GncRu{W<31^(M@<3hBPh! zm>g?c7zNvy>|wCNNvC(^{*=;eVNcUJ7;T&{z&12RQg28Wr@y%$lcsjESeQ%e`;=?- zT#OqV@Q2(69TackbepUT4&?27LO12)hd6IKFQ9rcEP zCQZLE0bnBr0*^6l)(CVjcidXgUzT+1sd7@qC5{)6`zZ+Q5n5(!6?h-cs-kkaw7IRH zk@nXQxW;;2Kc{v=?ho93B<<1OB1kQ(1s#>kOqvl0Vo~X`mbOi?$WlUgDKK>Su7!kQ zyYk5eGSpmTVG;TLuD1G>R{m^%r&Qs4$zcyc>9p{14*B`TVIO!-v>t~Y(o zddbUJ_t?zAXu4hk?D6+VOA2PWe^fL4emI{9&%QOX(F_{zz zJ*0EjH<4!ThuV_O&>N>chSB!4gLCH9=TvN0h0~IW_KGtfqQW$sGo#SIfB+^+nJh3z zw~q{P$`0F{L+xBt#P0>W-sEb=80;3bwK#us4u?1h0dA_R$DYdNB{Fg*JMg2kIdi>* zFjOrhb=1Vh+RFezQ+m=~(ymZAf05hy%rS|S%dED{3 z4=K5SR>TR!3k0wN?4X3|Heil02`mODXPKze)K-?XWC=`cWo2kwH>}+9IT~y}S_j40 zOMyLtq+JC^TPZ}G%3XQRd{ZU)qDStg6)X6Tqcdf;KYATozzGfb*HXEsi;Nl?kMs=l z7x+9Lm-vEDG1YCr9zhPFqkySRJ+MdUZQa4?km|}E6nFGPI-V!E1K2B=W4%AQ=-6WzF`<#W#{d?ix!Hjll#(us z_XqS`*JM;2s%*9oKsQBn5LUMv0DFXSV*@zJ4l^90xI3h`X@MxypWV()QVk~YS*PY; zwD*?+>`tonRtmw0uJj@rtOoOS*l>m~2Hu6|^G z)@#T~=#pDJ~yoAbXfXyfpBUzY+gjT~T(u&1Nz2|+gd zyH!#!|8;>fRonWMKj_MLjyCY}WTdt0Wbt6gVm220| zMzpwdGn4j@rx%1 z`INQFS_h#&{ZQZsQSiX(qB>2M^_1>8e|R)*`lgn<;fKhUA8+J`=3umo&}@O$Mg04& zP~F|q_WRm$CV+=K;InhtsRB!s`^(|;Y&{{mU*1r^^&@oWlLOo!GzRF-iRLjrgHzO~^e{&R{i?D&z;c>ZW+d1R z-WL+1PLqw*9f#R>?x%7W*KAdPR3NU&|G54Bv&bU~s1vP&YlrNC9|RHG4~}Z@U3O8q z6IORM6=*~TH2O?$IA^h}#M(*v8(svsBfLRol(4wXWLTWHGZH?j+rCwOm3{(r*EkH! z5xVXgaB?VL0iTfkji%WRhBlYLj9pG*R@)B0+aHX1BX)FTbOvBeoPX-6t(*@3e9Z9P z8{zluYh1p^oT$aPzjG6Fx8>IHe;!7s6z8fterLO{B(+-oFlRb?--$*=QUZ$x!f_vM zHae&KnVBfPa||+N8cx^RVQ4D+uF$Y#+Z>GUKDOl@sC%kMZDwfUv_e>tf1%0tLl>pm zL)&5Zs(=@COTUU%b!fpNn+kV@S(D`!dsf_0t7w?$E(JVX;@T%B7Unt!ZlH2~l;PLR6*FL8leaGCE zVBM2gQxDA1n!^ShC7<4dmGmrk&!h80hc~b)J9op^l{J4}Un$XduN6s+@7vQh?q!IN2s>Yi=_O-3rI^k!9&eYy4fX|JH zL8lqQ=9(MA;zo5hl6rg6fB&n1p;H?CFJ;2PeF>Uy@ll{n!)oxWb_?XFT;jk`!ls21 zi&Wq3?A1HB0eyuAID8an#-~6t^Cj>6lgMJ%H2r?pFp4au@94Bz`UDomZMiYP9zkxt z0LN>uH&aWG!|{3|%SI+cqrIPx{BrhR2;C7_(q(|{*!07i+RQ?}#dY~tUfgQGTgVu* znIEroaE^8#_U13EAuE8&jnHhl8qD}H=SXhAsr%ytp>zEu4*-AHjlRQCm^JDV(!t(K zngj~hoQ*O#6rRp7k9CGc2<$vo77Ycx8W1psT?vCFres8!$ <~%BoW?|{ zoh$hi&QzGduv0tZWr+YMJ=!YJxsPcWhbUk*M4LpQIhFgAnD+XW-%@8r_X(??8>P{r zVOH-D{>^|t^M&1r%4J)&)Gt(B!)V`PY18IemJS8`AMd2mzBP$p82(QB zVnTW#1@mg$Xf;jm!l9tV5o`Uq^)&R>ERA8S{y2fN@rVoqhRvGK)z4BU_1+JzZdT%N zxT&)nl#Qsn=3b2B(F+4-MPWY}lUZEP3z=Hk+nqM4O7E0Ka<89*T#G!$E%=cR&KIYe zV14v=J}aDW^&M9@oM%@c!B!UQitYixU5gurEo|-p=g~sh8fr6>x!)e-+$YyLbB)R(g-Ug<|JNT!XyIlYAiJe>qw32=kfiwxk%wUOV4%2g?9 zp6yysqx3{0UCvQY^f}<(tqehV@LPaBghDsW8{Pjr$o^2A!S4H(yTl~r$h))3Nr!N5 z1+YhN5c|M!)fM?~l1@W_^cuICT}&&3r?%9q3*kHfjjM+XA>lJ&u;t?q#sbUwxCY=UkYrdi8*?)JdF! zqla)C0FGa76MW(^%U`m$w5_DI>_OdtlP(UwWPan^FtA6fX=8BQ*)e*I(mfmT-HjZa zTO-p_`@*Joo~6ezv=#?HR&*;vkk6@>N2$&HWiS)}?9+fmaZuvR)RZGkLwl`i}B52_pO$2OK3XurVcb3eZ9Sa$#})ax*O zdHy#jelntCS^ah@3_M|H#)i#Wad&LM93283a9nx(9rg8*^kKE?$lL?kJd+cqOIFy~e@jPEJ$Dn1(ExJvi{iNLyv0Cc^Sa z_RTPOUWhJ({!g%(2oE@~ukdZ4L`6kdhgL%RHlz31r9FPG>-Zt|H5_6O&`gLR7q)+g zPt;~*u#5Yi*xtL&G^mlHD<$w}3g2FT;;D!pTL1jb;FI^jSy{IBFL*u}~T*dwZmGS1nB}Qentis4uq_V!yDw zg&@+Hx83FaJ1Lk*@@Y#k(Zbsjtv_#gWm&62?57s+f*>q=!EwDiGcyGfX4h+CdG{ap z-Z<`&)2Hd`@V?OkbM%K!Z}g)fk8M2^jJ0qYk^RraS-;Vxc=B@R4DKxsn4^^nc3Z*G z67G#*vj#3SUcyEA`;+J!cS|f%5{mEyHfjYq_5g6s;?aX^br#oc;-j2=mHv1C&G+$N zIHG-^zuyNThhTfi&|WL}o^clUcKOBE7WQ3Y6|4=v?%JzFKyLgGu!9BM-xQ{MLzQXzsbujL`^j{H{^4=Fds4t0eQ5gu9OGWaZKsTa3)iKf zl^Ek?#XXzU2;2sI80(UqfSMCEStv-wryz1v}+&cjz(# zKe|G2G&n~ClhNN+?kW`DcKq-ngC9QcTCLcvUgH>+m(f<{0&GX~#so?$-HTJ7cZ|IE zaGK6=?&DY&>^Zx;gofd0;;fMZ%~>pwN$|HWMsut$G9;Ba|Gz-NlP zBYCX%yY?C_^9~nG`0`c(CWkH>Y)eHS6k>ax_ay{A2c5MJ{Vedo);rMgP12z#94jYE&*fCvwO2wkIu1e87EyMf`@AJ2#a@lcT z{2E(-*yQx>5efY`zzI1ps{hec0iqBXR|J2_dTs^^Wzs(e;hb~5R z(x5;3TI`LJ3E>P4I3G#dxrNe9_k~;z2KQZVA6mlr_(xYF7R=r*Au)*2peY+oe$6}x)m^9b zTg%f7EuVbElQzE?F~P@N2+u3b*v^;IUICxA|D7syi9=S;I^thCBrRRs@Yo2Zqb?x_ z=#J$RI4d(V3Q}6B!fLCPCf%z#t>J#ttNx<~9!z(LF=G>yPSn1Ig6(XHI-K}?wap1` zznud)BJDVa?T_fp^ai+=X6XpEb8UhfkGl>mITadF6!H7wez^a13Hd^IT-dtHTbmL= lac95Jvhs{D_ty^^HS`Zws1M-otRcpTKAl1DnJy>3`9BF96UG1l literal 0 HcmV?d00001 diff --git a/dependency-check-gradle/.gradle/2.3/taskArtifacts/fileSnapshots.bin b/dependency-check-gradle/.gradle/2.3/taskArtifacts/fileSnapshots.bin new file mode 100644 index 0000000000000000000000000000000000000000..5e42b76f58dde0943199e3f38752227725956fd9 GIT binary patch literal 101397 zcmeHQ2S5|o{|{mdb<{-M11+NBNXQ;)tKvYdD2gI#Dqij`A&_MT!|@Y$-3yCVu#UR- zLQ!$x9u@b-y*F;H;{V+WAsjKaU`zj}oP?8m_ult?-}imj`+SeIWwENUKazh~4u6s} z4(2%g$b4idz)*mp07C(W0t^Kh3NRF4D8NvFp#Vbxh5`%)7z!{HU?{*)fS~|G0fqt$ z1^y!xIMNdgqzo~bYSL2phihlP`rnZ_7K>jF{8({x%#F&~HFL`ozjOBi6-gMcXcO0` zbZRDXe?ndA{fsp@hU$Tm}IQ1=g2o7T$6T6mcF{jtsM_ZN)J;vMYtg1GsFe$|0b8Z-}HLo(*2iUGBPr55OqKBH2b@2vxWn@V1H&;q3(m>BdOS=yyRTn3!b1E%^DjdIh5`%) z7z!{HU?{*)fS~|G0fqt$1sDo26ksU8P=KKTLji^Y3 zO*3UQ6bmUeW(d)tN}X1vH0f*_t-%8Bo52?sLakA#nXA>CbX);XAmRyl;I=25GylYf zDRbM5&G4(#>DdR(VKCkwag=@2Fbr!CW$LC4$rZ}tzKWDDP~)v7t_0qbHZ@NiEHY6c@f&8R*>8EQ60qp;PY zY>S#u1A-dhgf>wq9HT_+KXYO12A8CQ#SAO;kk$aGVl>7kC}E>sX*C*k7NrG+ZDy@C zL5ap&QG-QmG&ncf#%NG$H8wM31^?NO`Yj&Ok|&3CNZw)6EwM+l?ZNW}aF_b~meUMX zXVj=5&>h%lMgh(F7}YVFb681A{q9}mTih9WDtyV-j8dwd9yE_r6G)7P>o7_^WPmiN z9yM4238^;M^}6rBslxIR-^!Of{Wj=I>jxBz%-i2oqME(GzO!^s)aE&p!%`2!m8>2>-2J8>4DYeHVQfBwTPx6FcW&C z!NS!VK@TVnNLyHLT;+#%Z9m8k-!heb({&TggCs3fkOk!e-iX!0s0Bb2udux{riP76;>f1x2|q~z!wf!K+}(C z2yhMPJN6v$)b;L>^HX^r_0apsIc8&E_`4Oa@95K72aZU%H2 zaUhBJ{79$cE7DK&o|ECK6=Gq>K^mih8)dbcxRxl$j3Qz%8iJ;5@0RO$%NjlNs--gr zl(V&{w#;R7RvniQMkK`h!v0Rs`dsL?r#Frd7zdkQMOEDB;#qQ9FcD;d&03QqU*?Xu zKD^u76Mko|Hda5IGUli&!jSD?9BMPbXx^08@A+Nlil+l|Z0Fzbm$o0if{r&R>XMD< zAcMvRmI*gHR-f0<;G{18Rde1aPB8Avd5v1XUiIlwX_35+a9BH5bqjfLy=tj?{icc< zRN4P}F--$x4-jL%g|X$>(Ha33Ucaa-iqx7HJzlP%dD3YNu+5-#q~(q)Bfd$W;nnWP z#RqrP@hSb$o!&dF3=V6zVvN}Hp|;Y%J_GiRYT8pm#}Lsr9oK5)T6Ai0G+=QV_=~YP zyK;@j#-S}gPVN`xkN&3nW2+ksK@5j$1FMx15bTi7r}mfqZPFS;Nu%A41t}+qSPA^n+`}Ep;E2Izw-pxuEL8FB9Ilrq>?g9 zs1yKMD3D2&YD6Seh=n4NSgI1L1rnhI77IkENTim-YK26_SHKD(tU|yufX?_cq!>u4 zd@|lAMsV}P@04LC1Ir)8VpNC&TvObaNVIaO1Cvx|8kq@Clg z;~?_bR#9x=p;q^rp9>M*e0ky5F0LdVxvogALQrfpCZ}!iO7h&}e^{!Z-qCOSzL4>9 zx47t;v!rm^NI0wr#Q6tb#~W<3|**z*=>@}nm+6ki8?8+5AO-7b?Q z&*_vB15jmRQLafxHes~Hb0Iw<6@$%8K<(*AE68xgekUsIILT@TRg6M z{lSYan<8RH9B*>ZjlDn*#iEYFYv$?uy#*JpBb(I|f0)to>a#trbV#y0q!9oc4F;e| z8_irod2p}?IIL7J&zae8%iS048@26L`9aUNxgZq~r(lpO$O=bsRYs%LVl_i16BwzG zN3DZdja#(PLM0+Yg))f>;!7Y%B^wCa=9200Kw0fgUjJLFgR+L9d~2W zm_NFX{wk$Z(vsXC%2uNr8=)RRCQJ*aR0Loa1tsp7ex{Aa-0aqYQ`}?euGU$!1=u3s zd7wk%VoyLSt?0QeZ+f0MTKV*I{~w;85I$K*!+=IrG!SJLEoQ+G6T)F_zgD$T?a&Q1 zCrx;|qKD*4Z8t1gay{UZH{T+-gNTl1o$X$4Op~6uGY_zL&7SqZAgs|L(lj7W?lbRDZZVjx>EB< z(ME_z3$Uz!(6)fa_;$l`*7>?yZnTMOQWhC7=WQj)D_1H8*%~1iO=e>(pe%5n;A~3r zXH|{QqhIGty#0VZgi8{&edXBzsK1O4l}L z<;Aj*fZZ^FjJr;-X^jU2p7HE3}88*~B)7e{tipuP(E7XR=b=SbBtgq0Mio<;+?3-fH^8 z_GDbJ@4>(kH{DPb2nGfg2C8%5UbZYn7g`JHe7CkKb?0h7eNR_XtpJDMUV%I|Sw8b) zorJP2ZYg>FQX^J1t3%h8vpS_Vqo~S)aJ3@2G*6>qcl}M8(<|lmFj>S}ug%_3vGeH! zB%uRgrVU^jPqv~%?^yrG$0uHzkQT6Ja+ux~QOKd>8S&U;=Zz%2CMRp-y!}hBu1xoy z^1W|(K?A8cyoH3m?(8ZI#!bXf+})bzAUv0`xPtj)HSlqn+W=D)qo?VLla%fXi}b$ zx;pR;a}lk@gekSS&Q1xX-BmZK1C4`*xA|2+M_K3cq17}jPqHnsik-|!_E+EhAPQg8 z@A1{BX=@GZtqt7~jf4~5f%DfVd;6rQd|%zwEEh+>wQ>)B4vSzu3yaOb1Kx2R<|5aD z4G!>x1Zc#NOeRo?QB*2aqheI9kSb821XT#d5^!I@=L;oLff$h>)MJ1dz+FC3#1djfa8H*$ruZ0>+E9Uu%<5$TKHY`ho}~knG<4+yU)225t#p1 zhg!+aS;7_af#nMP7=*C#md`w!bfiJGuxU+~wqA8(3Y{C8(4w^lEUW;=feWdCDYl#A zr_7mSy?wCqdbl=k<)>yjpLWk-9rhVHZP>fEyx#*Gj{JUU?$54bAX?lvhec5ES2y%j zDAVHB$80bC^lsF=@=aVQ0eY~AArRhiG*1_$^}C(JKfYpL|9T64FV`yV_UCX0COnLB zki}Fms)EOR0GEJ0Q=mk|YB~6VQ5jzdzRQ4OCsF{{mOv_&^F?xCHo+=L1xpKQ2A6r% zR1KX{Lp^zarO0tlf8N`^Y~o5ft}&x(O#g%|dhjS;hPk>C6d~wVHz?C@WQBFU-}@YW zz5AC40Ugsg3l5#uV59L9oG{c(99K&7YFPRE_ZPR@{gQ49>|PsKtH$gP%yEZz1O&iZ zCDbk5q~@#AQCr?lU;lIc-EP?APKqn8PJp$Mr@*osU7T3`Sh~08n;v(bZ>^D3A=B+v zN&CjG$2v3`JZ(*xsOQzApYB(O-Yye%mrj~dBQ>Bg#we>E3mhtVl$qAy-ZvW$rD>K7 zm}C$JD)0Ps=5yJN^ik&bPGPHxbW6bs;D16SDzRKD0%kg2B!nSgR={$h7?`zuR4Ney z;{uXUekpuG<~gL;hO@H1xuw-?X*2dz<@N0G1$71Yyu7&0gDE8T4H5rA$df8zRDdEX zg+L4|#Hb1u$>nOkTnbC&LK!Lt#y1Mf1Q0CD_aKnzMBJ1eqO3CAYldyT>d}kJEVyh2 zT`ZBBif9XPwE)K!PeRHoW74A27t&G>m$6Aahx;{q<;u@U?oQDVY=n*WJ%t^70_uM> z`^U~BCVe;Y=#sRSbnDL^%hW*@ifYb2SypRdt?%bo9IeT6HJEr63K_VhTmZ|33M1aG2DePRpE+~suI4lM z&SvkYvt;O{fs=~ct~|^9duG=U63qhsy?d?d(fI%%U`1hzg4A%id#g8Ud&Q%*B^Yh| zW=F;Imx^>vSRezUGRBk3LM)ca#4?o_K@fpj2!StD4hduu1%yBngSz$rVx}`--4xyWQYUXge5sPFySdH~OX1AP?xqC`-=KC8-Kc4oa zQ`xBJO@yE$l_EY*4mNC{Pl)WX&wFTvQ$Yq+m2E!U!AZw_?zp3~IT}qgk~3!b^vk0! z?R>CBczWpD2HC@0nRBET=nzh&!l)cpR;fs-*Wv!D%lc)`<9I%t<0^)!f-!N68KwdW zh&I_*Du=bM)Vl2JtgFX2RRY@E^*J|PZ7x>SV#R~QSo90m4&rxDAC+}3b={w}rq@ZT zV=G5zyiv3!$3jpCD0@Jeb=**VL;a6Tn7ihA+p33pX}mT)z4^IpT8O5A3vW_U0MRc< zBo!cPxg1y+KpsL6tWbgImjVcJJ_5`P;Hi}H-a%?bZ{vV7MH-v>uy#|`^9Zh6rzPAr_F1tCHrlmd$+GDs)}yMagy zR;LuiPGDFC++PZ*KqQC3ctsEdA!2HAl27MboVmk#RG+*0`D>*6if+b_X^C`!QcV8n zAP_4jOchEHaaeOLKXi#dlu>W>%QCF_<{G={)L4pJELc(ywypuONoIo+dVceCey6tG zditG8@3y0r8!j^{)PZdfaYnNa!5mbSP##%x_REDKwGxJg2-~U>e!1*Yg`rvkd}}md zek#Yi;-0Az=p`=RCr*6?HfrhOUiqig%{ zat@u@LOu$dc=kOUc;15#Bfqq-mAYf{g3~jy8l=#13pL>yA`DJV4?D2Od;i3NomZNZ zJ-FwN?)ZKKjm=|!7Wa05eb;0JBhP1mY>hr$PLV9(v}-+W-_-dTZC!aG$uR)_)nU;h z%En&$qvgS+iMHyMZP(GvacRBX*#k&+(Hg9%*<=J^K;WbXVwciWzdO-#glNK>yHnSN z4jAvoSUm0KxGClDp>8Y-LIxAm!%bBO z9lYDEba|sI?G5#BWF(_+C$(^;?nFU)7`Se%R5lr@alq51&4aTKZy7G+uy)GCXZx=0z37prQLW?RCQ@v9D``6=dZB8wWwv zkWGhaP!jML-{txuNt>GJkEcae4)j_vdUZ=W?ahf5Vc;?a(QHTu5*!>@>B+8L(q3V= z)!TyOx70438cxTJBp2pSC(Gl;4{sZtt5%~WmQAM~I#UBnFUT(z*wyD;I6OBn>$^Lh zhcCWyp{C1>rf58)3v9LIM%yB2d%wkppToVXEZ-WGl3t!J*oiqku=ElMa1>F4-+QFJ z&(doOjsqed-dEDq?GvCuoI`^4FXM2#-h9&J{ zTMZG0BPCzQy-3BkSNBdl_w%q|botL>_pMF~9<;VwogCKjOHF3Hsq%bQ$6@@y{vW@) z?uwJ*fg1$$gK+%tDg9>Fz05gnliy1g+`sIrKeqLOD@hIv1WiHnfF1R5am2L9?tWuK zuC{Dnuj>ptdF3Sei1dp*d3C4E$b{F2ddHO=UoJ3bP*iieUfAVAUO*S9F2JWp$Y1Bk zE8VU@^@2!Sa!BR^^5s^R#*6n3JaDnUP3~$^$jP+_1i*(p`OOafB!bv&`I z!<5iIb^Aq3TjJ{V@hBFK?TBU8V|gzGB{{4&UT^e6QrGpn_&&bzp~3T)ey*pU%#^k} zkF-W5(A<3U*?M93E^U__1rN2~xi100?M-6LbzLz72^ z?Ci`*ZC~e6rI+Wn{zA78P}58r?gZli-%|m@{g;!b2YUuRI@|r&i(7Zo4mEUXYZ#yy zGy%eWiKHS@uKDar7vTW&1x}rfsbeosr4s~HUFLDrFdp2HV;T~@~~?uaz#+iLJB z)1ZBBY`KJ1hAFWYEy#mP;ObE;@S9k%j1GG!yIZw3Q|n5n?r6Av@6eCRy7%ao6V7_>9)hARpYs}l^? z;+W*fVO?7zvg*W5R%#k;={4lf;MH{cIYlCJ`t4C+=S;DYyg|l_7wV)pp7e9*xCuvl zU8ZNG^1AFkBCLXZ91T8LnoBIXcU?e@L1G_6gGyDVzxYj8 zYSpp<)sL+{UxLOUqQ=mv%8~7BE1)??T1^RGvF+rx5;O*impH7~p&yg>TzM3bk&t|F zPU?_}C1?<0aw0ga-)}bf>G$hTe|l9vF68Hti`N$Pj(+*o45H;)b%Ooio5MmDPz=Ny z+~)A;b#Xu5*>kaaUH0vx&q~fh25H)aG~%#QjJ$qLl>GP*+gP>gb>O@GUuqPEic*Tc zeG@yE>h^nzwB7xso#pMCNu%tkmYAw!>h*#NlH~k_5MJLq9d_bC&JXa`fCe_lD)Rn^d|4 zEl)YMJUiXq$gQzHfd>+eF5YYNAfjOAd@*tNr-H~}1y!wfpY(o}Zt*rr{Vuy#CaycKxQPgu@Ks~=poy7C{ZV}qJ@ z9dqFC3lUeHA+24?_;mmP0O4LZhG#Mx!C5QJs`F%*da`!&>cqQ>wN<}fq27$@F#6r# zWyaz3O9r%?j9nfcXZ}9@2-7r=c)0C5bX{thmp-1lQhyfD3qE&>4*mTpq8o2scmD1q z)ffJF7n`JS?}F7mZ0s0aaXi)3D@GD%j@&ENJ@)k+!db!&T(%h3bmO1BN=za=c5+=P2y7u z72~cTF{1KgLb*rXzb|AMcSTVMdlw?cg-t;T`oi56CBgbHaW0krguCKjX1$!B>uKN`hhJ$$iR4L_bx!$`K83#N zDhY!;Tta5^ei{X|gdusBAhA_w@&H{Tt^EXFNkk+4H;B5=Fly=W%BUqsIt~%HKve0{ z;K>H^C$BqW4me|>(w!%va@Sm!*7)ChxWR4s69#a(hya)WWr0UJhhv_T3$JZJoL9v+UWY@o4E{5Qv%%m$g9>zH zpvZoTxft=EOHk0J&_h54aVh`uDFb^pIbqGy9T_GTv8!XZ)ah;xi@~sVs-G@3gf`Hm| z5lnZ0yj`V36fY2W3EG?r&yD|oize0)~O1CoAqUF!XF^82S>AGDK&>ldc0NPaNABN53ST_@nb|ki&D0 z^_m8d!_&QT@j(i3#&-KaJEB??El+Ppqh@qz9Xg|nx^jiM7w;Rp(|4IKX^ zKXTnF9N~(U-K+LM=i{f?kMus1l{i0Hdcu{v?8_C7pcCo#0ijktDgsDR0^%zF3+OVz3I$i9>38>+ zoJqRDo-p8kF}>D4Y_%EEqvS-FOV4HTf9-*GJ*&=m|J%)v*NW-opr|4mPrlPXWqj`j z_0yLHWWQKsSfvcgEGnEQz3jWOqz&*lN_^Z$qCCIF;SELf_-JigSXnQgh@a@t5W7?0D2;Dr;}Ia_Lx&0$R+(b%JJU%zW}er@Y%`Kq1pW-&2P6sj|E!3re#r}rVG%5H6$GOPOR z-11vkb1ktk2d7CwmR)eEiGxjGQNXp@jq-C^6Wf?h#2n zb*0$}DVrN4XDwjuU)%DlzQrY$2`z-Dg^ixDiOD-X6#-NLdCon)WL#-a=afP`9P?lTa zSLH7#n;CtU(PwePh0$k8vBK!Hz~Er?S<=Zs=L5)-{)|4W)gekJ>+uu%?6aa$60lkq zCYuU41ENB8HjUO0jC+RK0w+Wj6@T*b6% zk22sYgBAfBzBc5(b9Mlv^{v2}A`Em*v*(7S)0*pb30>|1SbB zwHvqrgQj3z@x)~_*|uqJ_PG=6zJEh?JO@J}q{o*oH$ z!s@h$dlH{7FYv=h?D|6Ug#~Ug$1%3myzWq1pM0-Zg)cK-4sQm2$XOA4W{S3UIqrWZ zEJaW)80@($R!rP)$rw@Ej0D$U{7U~X0`-@mWK;(E-fD5ia4A^wg2;MMx>xh6Pyzp0 z<=hzL`;S{!w?E(u2P~jDyc!JwXF6BF6Y>N&EI5aCy?f;RRNhBD^geQq*%%n^>VRQ1 zo`Gk8^jd=^e2!QW`ib6iGHBjSSjwP29fYHJ#X%aQfg5GDnz)uI z$c!RlE=Ur?d&Tx{xsJE2(KD}FI&(ldTZ?Kg(_9(kdwQ@S2Kk;~CI^jzt%nb!0ktq0C(dNuKCK_kLF2nb%35P_@^R)jx?h=J21%i zz!m6DQCl-gI-it!NNZ4rwCmBD+p$Y~>P!;FU?3AHUxi|q{zW>da&nW;2bahGk09Tl z`1=V^m`@V}av`(q>7w7C-fF^3D4d6fdSTJPK0j>iQ{N+f))QpYCNYE0ue6}B4J7X; zC|$S@%&66@MPt!$o6dlmA(d9AwQ5oOzD;2cvMqu2U#+?y*}|*(u!*mphG)|;J%i8B z;PdC5AY}0QN!6N0b0JQJG5GupK0gW$+VUx%o-;oG*#bMQn})vuwW@X6c%A`O*>sSS z_{PO|Tp@653Y92dgh(N^S`Nuo0x`meWvD=o0>=Q%SBXTZL?Tj1VU>dK_$csDV1I#c z62xLgtQp;Q;pOd@st9K9uDK~=&^j01Oi~#llc*dV9s4G1OnfS-@YTq{yHtY)m%l-` zsc38<`oxV!VkBIF43G+YJ-bN;Qg6JkUww6#rVSNcMT%7}-X3i+fmaG}XRLs9o_Z~N z(IRX7#f{Ity3E#{$x3x~f|Kk$;jhsev{r`!Fr@^TQUZlIItnc%FrS83L9_srfX0Ik z#PWKbmGP>%=1SQezwbZXzIdgHVo@%@NU*AnW<5Cdf}$!5!gYpJVSxG>p#GU>la4f~ z7B;Qv($=ePOksff6O@0s0*iaG_D?$=KIP-4jAjn&b?C>WJy#wDWF#aXoRd0aA_LS< zXA?0%{Rjw8e<|){fco)D!b(^HA}@$UC6-G?5(wgpgfJvRgs@yFMo@^4N+m)OB!(nZ zLs)<|-i^Z<(;Xep@QYDNEP(-B=h+%~oRly>;T+NqDVX0gwL**(2M6zT82o~mh z5Ex5RLPZQwR+;WK!?s@a=tX4~TsFfME?l$)j^gq`cwIu|;INHJi%wriOFdl1Ch;8Z z*X)%mI3QBLjD}z%Y_uC|?BEj+Q#XJ-DeRn{R>;W*{4_Q&_H#r2r+XBBZ*W`WR$A7_ zhk94kXX*yXWMY|0j39_WErh@qDu)Czi2_0(i9#+HDMYA3EP*MpLRKBfSKfTlHM!5t z9pzbJLCw0QMNAHH<=()u!${FYd1u)5JZ86?k-2+Ha_0LRNk5+UbY+d12wxL7*ktWa7Yo52QdZ?GiYtz$$m9gCr;h52HjDswuf+?pMn*f6!IKu==ko^ORqyj`Omjinr z2yh636)J^9r2v~C9|1-`tdhw1a{5+?^hhc{a&_-Z$G#5w*0{do8r!g(Ff$!Op)+bG z5bmTekEt7gp#uU`KnHgXkpx1C2&QfTQ#XJL5ioTFe$&1T_tCX|csYlu8{kgL3kj)1 zB)ou4#~E_%@B2H7rEb8T&xw6uBGh6s!ZA30P@K^mqr`s%dA9i0$0rZYVpf4tCKakx zYAGyH3&ko3QmKK8hQMkCtQJYdGJ!-OQwY>DROQeF*!LWpAT^{NU+qz6hAx1;<_vx9 zzqoYu4KyBpC+D{rH5tuT?2JHO+V9rr)8!P&5>C6;)AmiBpV4;Br<(zVwsd)*sT|hQ zA1x0qO|(_7Y`czTj!WxZf=&%FB@Z%^(YKRYxU#L7k_V_gk+_7FJSYfa=cX=C&AF2L zK*=(ZQY?go5(E|r1t6VYq2{9!gfHdur9f%{Ka5JOP^p0_2l4Yi3S^jw@W{Z^rOku0 z4{sSREkx7|;l9dhTXZ`y!uZvt*SptIwh4J)QB z0})GQ$};d|_H3QQds5$bIrF&D#b&;zmvrtkht8oyu1}^cgOk&SqzgEr1v#o(cgl=R zczvjMT-ovE0&@mMHK%iWP{NZq6k6P684AKVy0OK;8Z12#|Ceh3!ri3Av%HjuSRz%a zgd&g`24WGwF$Bw`YL!rqf}I8t3qc@4q7Z{h2H4}ogFu#34oD7b_4FH-v)RvoT5}Kb zPdxv~hbbAcuHVJ?@r@4+p1<_q=U6sWWJYVWhgZNyres9kl4OT3^17^!UEC3A(6`m# zQ>H<#G--;Qm_7r8EtiZ@^)|iiFk-`qn*QlSIrXIDU33e#OKhhufIz*~b$Z9jAks|OH))_6}vw%kg)z}e+t84eL z=GCem@W0uH%dE*Ad|kO-3%f8F1MAFQEbe=pgW2N)j53z9CC+44<`#7-FK3NLw! z2R6lR!B1_2@M{YLx{~k27;rQ}UoxwM0bTi*gRYd6_0538FyJufLbpA=aeTly*!(K0 zq8n!;Fqke2Y}T3_&qm~qxIVnw+7o_ft~ORbn=|zbzqI}E6>hkw?8-`XtUj-y!AV{GtLD51{{WP z6Efg13^ePmid`OK-B`mTHugz<#QBP(8GBcBb$wu)i{54F12{9K6e=F1De zc5wyeMG6x_wr~+})LLgW=}}M+Ffa0VC3)`gKP**H@94LEU&wg5bbekZ;bfO`Wa3s{ zV>uo_EEwc{e$9||ws9NYJW704)P@C)obXwO#itVIK}ry1cBB}2{hBEG@gcUcYSrt& zcS~r3q2$m(*%+Lb#8D&;Yy4u!yd=>x>E_az6JP05+J4$dwpq10M2VO3i&qHFnD2ZHTR4qkSe1s3Od>L>Uu0^XcASLn z)WiQ#@V%ak&{bt?yIi^ib{+!`!+^s$r#Tl)X3S@$GvF{N1*3z3clk$ZP-|v8`TcoP;=6Rrz?6$uGDtrVkUE< z$r|kVP7EU80I85vEAJqpqgiLW*BjHMXYR}c>|OI{6afZyg@IjBxWe4bmw3;>t}w7G z4D1R6yMh79$WnBnwUEwtYnxJcuJ+USbhT5Fmb_g{B!Ic|4DaPLKh{Yo+v1jz*Dp0< zRkJ#DZ8>LaQHT#(kz9%$cqGrnbp1`5(<|lmFj>S}ug%_3vGeIRJ;KhhXY(mK^p5p^ ze0<`i326aqCWq-=*+}G2>`nyCf$QLpNUzDs+Bk3j(yJ@ey{CNd8(!q`)#7s@Ft97w zT#|T}`9M?cjwl9pg@Ij3_V!6p`M$cVSuT!%Yvq1!N)pdvGw{G-)?uehbdX64ju%P* zyci^t2~=Vf1t%;}F)CL`6{t{xDuiMQxDQU33MEp2IwnD=$AFU-JVt8#%VXs|CnYCM zeK@SjWS;N6K)O&3KuZ!wbB(beUzR|f#Js$OpBGeAUmmpZyXX&5EhIB1#29yQvA3LoT>)E9Pe3J5lma!QdIoj{j^ScfDh8c}pQJ^^ zYB~6VQ5jzdzRMHjdbmREvoA8sBZ|*dP{f=P1#n>aI5P z{JunNOLuT3vRnIB_x^6pvRVskeLuhAXiZi@OvS&MaaovElUK;w?n)=X>KWJ-GX4T% zAeHoMqtGZS37kSkP{m>fc7@BpuFzV(`MkeC)|wy&c7@Hrt}w7Gg}I8z1w*A!=pc&) zU@7Pj?7S|4pv_^8tU3GT!jM`CLqmjZRSCab&cu#*6xJZs5?Fgi1D5;bm|2x)`?EFP zISJhL#&>hsv;ESyX4d;FiBP0#mGZ~3O@6#zGU8_pm|XX`f!BUS4Y%V%5CCRSLvTJB z!N9ICuq#f=TS0rCRA#;ukS7DX!oaTRY#LC;%84_B@uNqf`2T$><&uG2VPIGO3coP0 zEB|fSl_GbD{sTv8=~BdE%n2A4u#gO}{}gsrn$>h$%@yamPC2m49Cy%__Ufb#7plZk zh^ddajvSqk&|KjSg_K{cnyYZ-rKVheu#TuX4&DU-cXwP`Rp)KXa$aXePn%!5K4Ffl z7NW5xAOiy(19n0Xq_SZZdH^go8Bu8ww7uWr!_VPfRhDlJN=YwIcbd&PDT9HIVW49y zN)>FT8w4~abLEk=^~qhFopgzFyZEbWm4R2#PQWxD0d*1054FZHX&R ziAT)<4y~i!gdJr9;YuivgaVz?q-$AQa;T^^oSG0m(f5>PNjlnatK zZ90Gyq0$00FHjg4gOS;HW%acus~ct%8Ay%en>^+T+IG+xyJ=4s)i?;~SPR~Fi%0gK zXNIl4(0X&32SwGsWA7d5q%_*BCYzN9NC!03Q?)0YpUhfU`d;EUGatSQ`rnf;_qqG)BC_gzse8J1s^HBsaE?( zH;Sh}FsK!1u_ow1DM5?Hlilvp&x4cqHTr2xWlOt9Yy7WXDv&PnnX&Zzw5PDE3nzjL z*B1_BL=ed{`AOeB*OCsZW>(>x-qyWZ!NRJa+1-4LrANE49sr%Su=)B_SL3ni4E+7* zuI(3oSBXZ~ZPMY*r7=Y&{_+!63+%;sf`d4$o4k{~$9rA6GN9qi@Av2Q7c;xyywX2%`*R@@)LXO{Ow%}A7y?( z<)?by-VRk?c_H&BDvxzf`o^ynPP%zRk;>yQ(_@cjZk&|YkE=W}cWl14Vl^T2n99{r zL9=tj{N1WWGgZTIn^ckkQ0OQJQbZPR+&UmXZGp9wdK@^Lnj k)Z0(LGM&$7>ho(Hyphy)y?yg}VD{U9Z$#WXRNwCT3rn*0Q~&?~ literal 0 HcmV?d00001 diff --git a/dependency-check-gradle/.gradle/2.3/taskArtifacts/taskArtifacts.bin b/dependency-check-gradle/.gradle/2.3/taskArtifacts/taskArtifacts.bin new file mode 100644 index 0000000000000000000000000000000000000000..828c072fe12b486ca5052880547fca6ffdd0efd3 GIT binary patch literal 24660 zcmeI3e{dGX8OQfcLW_uPlu@CI#ZF)Z%n=#{3zdQi5HOHek_-&oG;{CW=FPpiU+(VZ zeWRljr$5qwN>Ty@`8m^;&Y-r{wu7SBc3Nv~gEQ?YtsSjZsf?YWLZv^({z0GJdpGaB z5mHhz4#RAi%X{~{ce~Gi_Sx?}`!E@-MQC#Q+58WR{p>jM(&^ZxI#mP|0YyL&Py`eK zML-cy1QY>9KoL*`6ahs*5l{pa0YyL&Py`f#%Y?vSGYn)xG?>ZrOT@`r$HqM{m_?{+ zB3xe4y=dMY$JQ85bkABU|0m(_-fK3VoqnJ{vac?a_S3ny2TtGOu8i!Bi=@5ebMsc! z?5~&^*^_Tc`|J;Xeej0ullMgSx}>x(o;uD!B(kr2U)sZaj#r=k@E6ZU_BCD7E zC<2OrBA^H;0*Zhlpa>`eihv@Z2q*%IfFhs>C<2OrBA^H;0*Zhlpa>`eihv@Z2q*%I zfFhs>C<2OrBA^H;0*b)pL13^Np|S&T?Bz#d&E_whc<_eS4YysFymG<7pMLpcpQN=k zF)RmbMqq2qpzTyMeK)YdvV!=2M`ulR)l!R1pBM~VKqm1@qGqAqOfjK)1{3Ud>Pg~f zu*s-iiv#Rg*fTq8+OXNKTSM2CCO1?@{pqRDb}Zd=3`#N8UBmVg(DK#0{D9fMM>Pwl z!gNFaLfrQFNi>e3nIrmK8++=JqNe!Ml%T6KMu(v}hL_gv^nC{#-qC5K>($*K{;dQh zHlT4Gh7;mkkk~FC#yN&P3NF>!gz`p$9cckZ`UXSwE!#^+?u~11T3&hkqw?uipR~&x zV}rP5#6c`CJhWdnRD?rZ)Z-592#5OQO>tL(J;iRe!jvwPV-W)Z8uMYUwY2Z2VY=be z^*#7-9GFOLrR#>wNIAIPrmUh76Weg?d$9%1xpHv;vW;jwcCd>*Mj4v4v7Y0d!|~2( zNb!JJlnX*4zlgZ!zvz8={l0QK(}BNZ$pz422}5Q4X@))#dA?f?D-JQ!;Vva<>Hj1# zn<29uZ7Cr}C-*h?;P0mHe9_obiV`bP83mt3^C(-!-OlYhSF1RO&1kd&Xg@PZ8Z#dH z2D4MPW3$d^dQ0bO3%1D?fEZsWiz7E^v2Gn3E8QZp zeW6_7C_>f$XuDSU{uEpsSpP0JXByN?zfdv+)HzoZe4yZDj#%750K$USrXy-7DV@7#Mx z>wWT^{_{0x`DXro0cXX77&GS3GS#C6;HDP@t|k&@{&K8n z_FQ=9wAx&s8!_ve`pw^N+11s|rIess|MxS6wx-;Px_mF5+4KH;CvPP%YoXq~}&r+^)BL)g_4`IUlJ`H3k>oXTXdL_3zOrf9IKK13eKY>;wtctr&HGdH zukSH0$#F=xf4sn z&!SAL^v`4U4&hx?LW&zYu%S=co~hCS&$F$R4S?#jGXY4=M$b1NRTFqR&8J7 zU6oaSd)cS1I(`;5qV=eZ?{gTsCbmItWCZ3BGAo9DFvjH+jzEX)sm`FrL3IkdTLODn zJ#fOb?G3NdtPmBTr1-8ez-C2D1r2<&y`>c!EF`$48vdD%PvLy7CU%F}5~SzoJ?H^c z%FxzJ%KMmuxn22~(6Gl-WoxYnku`=p6bG>xZX%c`({BtUw{APxy-}pJfv6hr(nK3` z9frndLeFOFT_^W26jWgA5%m@o2kM4xk8BTa@C+xvHRY4S7jFK+THI>D0&4;*L<`(m zSj;=5+p@QKFUu~hmwfZ9nj?Rskr%qyTwL;CNP|g)%`;Tz+-W>|slE#Kb$Z5Xhmwa@ z)v{nNR{~uGI6T`I5nT$^J0c2pquXyKw%BRUCwMv3EFh}ns=UDJ9NNmu2b2*bD5@dA z3LLw2UD(KMrJy5_sqm>1{f*Y&#JOrbbB4`hRD6{|B4%C_vzITd?8wKB+~yjLM^`bq zk(H`2qRm+-F+watO*21l|F3c_x!AQYl;m3<33xwbLCBIgf^Lj@7u`oYDZ?&Abif02 z*o+BIe7&zWf{8!-=ili,ol.inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-bottom:20px}dt,dd{line-height:20px}dt{font-weight:bold}dd{margin-left:10px}.dl-horizontal{*zoom:1}.dl-horizontal:before,.dl-horizontal:after{display:table;line-height:0;content:""}.dl-horizontal:after{clear:both}.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}hr{margin:20px 0;border:0;border-top:1px solid #eee;border-bottom:1px solid #fff}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999}abbr.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:0 0 0 15px;margin:0 0 20px;border-left:5px solid #eee}blockquote p{margin-bottom:0;font-size:16px;font-weight:300;line-height:25px}blockquote small{display:block;line-height:20px;color:#999}blockquote small:before{content:'\2014 \00A0'}blockquote.pull-right{float:right;padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0}blockquote.pull-right p,blockquote.pull-right small{text-align:right}blockquote.pull-right small:before{content:''}blockquote.pull-right small:after{content:'\00A0 \2014'}q:before,q:after,blockquote:before,blockquote:after{content:""}address{display:block;margin-bottom:20px;font-style:normal;line-height:20px}code,pre{padding:0 3px 2px;font-family:Monaco,Menlo,Consolas,"Courier New",monospace;font-size:12px;color:#333;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}code{padding:2px 4px;color:#d14;white-space:nowrap;background-color:#f7f7f9;border:1px solid #e1e1e8}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:20px;word-break:break-all;word-wrap:break-word;white-space:pre;white-space:pre-wrap;background-color:#f5f5f5;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}pre.prettyprint{margin-bottom:20px}pre code{padding:0;color:inherit;white-space:pre;white-space:pre-wrap;background-color:transparent;border:0}.pre-scrollable{max-height:340px;overflow-y:scroll}form{margin:0 0 20px}fieldset{padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:40px;color:#333;border:0;border-bottom:1px solid #e5e5e5}legend small{font-size:15px;color:#999}label,input,button,select,textarea{font-size:14px;font-weight:normal;line-height:20px}input,button,select,textarea{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif}label{display:block;margin-bottom:5px}select,textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{display:inline-block;height:20px;padding:4px 6px;margin-bottom:10px;font-size:14px;line-height:20px;color:#555;vertical-align:middle;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}input,textarea,.uneditable-input{width:206px}textarea{height:auto}textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{background-color:#fff;border:1px solid #ccc;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border linear .2s,box-shadow linear .2s;-moz-transition:border linear .2s,box-shadow linear .2s;-o-transition:border linear .2s,box-shadow linear .2s;transition:border linear .2s,box-shadow linear .2s}textarea:focus,input[type="text"]:focus,input[type="password"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus,.uneditable-input:focus{border-color:rgba(82,168,236,0.8);outline:0;outline:thin dotted \9;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;*margin-top:0;line-height:normal}input[type="file"],input[type="image"],input[type="submit"],input[type="reset"],input[type="button"],input[type="radio"],input[type="checkbox"]{width:auto}select,input[type="file"]{height:30px;*margin-top:4px;line-height:30px}select{width:220px;background-color:#fff;border:1px solid #ccc}select[multiple],select[size]{height:auto}select:focus,input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.uneditable-input,.uneditable-textarea{color:#999;cursor:not-allowed;background-color:#fcfcfc;border-color:#ccc;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);box-shadow:inset 0 1px 2px rgba(0,0,0,0.025)}.uneditable-input{overflow:hidden;white-space:nowrap}.uneditable-textarea{width:auto;height:auto}input:-moz-placeholder,textarea:-moz-placeholder{color:#999}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#999}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#999}.radio,.checkbox{min-height:20px;padding-left:20px}.radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-20px}.controls>.radio:first-child,.controls>.checkbox:first-child{padding-top:5px}.radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle}.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px}.input-mini{width:60px}.input-small{width:90px}.input-medium{width:150px}.input-large{width:210px}.input-xlarge{width:270px}.input-xxlarge{width:530px}input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"]{float:none;margin-left:0}.input-append input[class*="span"],.input-append .uneditable-input[class*="span"],.input-prepend input[class*="span"],.input-prepend .uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"],.row-fluid .input-prepend [class*="span"],.row-fluid .input-append [class*="span"]{display:inline-block}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:926px}input.span11,textarea.span11,.uneditable-input.span11{width:846px}input.span10,textarea.span10,.uneditable-input.span10{width:766px}input.span9,textarea.span9,.uneditable-input.span9{width:686px}input.span8,textarea.span8,.uneditable-input.span8{width:606px}input.span7,textarea.span7,.uneditable-input.span7{width:526px}input.span6,textarea.span6,.uneditable-input.span6{width:446px}input.span5,textarea.span5,.uneditable-input.span5{width:366px}input.span4,textarea.span4,.uneditable-input.span4{width:286px}input.span3,textarea.span3,.uneditable-input.span3{width:206px}input.span2,textarea.span2,.uneditable-input.span2{width:126px}input.span1,textarea.span1,.uneditable-input.span1{width:46px}.controls-row{*zoom:1}.controls-row:before,.controls-row:after{display:table;line-height:0;content:""}.controls-row:after{clear:both}.controls-row [class*="span"],.row-fluid .controls-row [class*="span"]{float:left}.controls-row .checkbox[class*="span"],.controls-row .radio[class*="span"]{padding-top:5px}input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#eee}input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"][readonly],input[type="checkbox"][readonly]{background-color:transparent}.control-group.warning .control-label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#c09853}.control-group.warning .checkbox,.control-group.warning .radio,.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853}.control-group.warning input,.control-group.warning select,.control-group.warning textarea{border-color:#c09853;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e}.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853}.control-group.error .control-label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48}.control-group.error .checkbox,.control-group.error .radio,.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48}.control-group.error input,.control-group.error select,.control-group.error textarea{border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392}.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48}.control-group.success .control-label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847}.control-group.success .checkbox,.control-group.success .radio,.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847}.control-group.success input,.control-group.success select,.control-group.success textarea{border-color:#468847;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b}.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847}.control-group.info .control-label,.control-group.info .help-block,.control-group.info .help-inline{color:#3a87ad}.control-group.info .checkbox,.control-group.info .radio,.control-group.info input,.control-group.info select,.control-group.info textarea{color:#3a87ad}.control-group.info input,.control-group.info select,.control-group.info textarea{border-color:#3a87ad;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.info input:focus,.control-group.info select:focus,.control-group.info textarea:focus{border-color:#2d6987;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3}.control-group.info .input-prepend .add-on,.control-group.info .input-append .add-on{color:#3a87ad;background-color:#d9edf7;border-color:#3a87ad}input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#b94a48;border-color:#ee5f5b}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7}.form-actions{padding:19px 20px 20px;margin-top:20px;margin-bottom:20px;background-color:#f5f5f5;border-top:1px solid #e5e5e5;*zoom:1}.form-actions:before,.form-actions:after{display:table;line-height:0;content:""}.form-actions:after{clear:both}.help-block,.help-inline{color:#595959}.help-block{display:block;margin-bottom:10px}.help-inline{display:inline-block;*display:inline;padding-left:5px;vertical-align:middle;*zoom:1}.input-append,.input-prepend{margin-bottom:5px;font-size:0;white-space:nowrap}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input,.input-append .dropdown-menu,.input-prepend .dropdown-menu{font-size:14px}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input{position:relative;margin-bottom:0;*margin-left:0;vertical-align:top;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append input:focus,.input-prepend input:focus,.input-append select:focus,.input-prepend select:focus,.input-append .uneditable-input:focus,.input-prepend .uneditable-input:focus{z-index:2}.input-append .add-on,.input-prepend .add-on{display:inline-block;width:auto;height:20px;min-width:16px;padding:4px 5px;font-size:14px;font-weight:normal;line-height:20px;text-align:center;text-shadow:0 1px 0 #fff;background-color:#eee;border:1px solid #ccc}.input-append .add-on,.input-prepend .add-on,.input-append .btn,.input-prepend .btn,.input-append .btn-group>.dropdown-toggle,.input-prepend .btn-group>.dropdown-toggle{vertical-align:top;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-append .active,.input-prepend .active{background-color:#a9dba9;border-color:#46a546}.input-prepend .add-on,.input-prepend .btn{margin-right:-1px}.input-prepend .add-on:first-child,.input-prepend .btn:first-child{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-append input,.input-append select,.input-append .uneditable-input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-append input+.btn-group .btn:last-child,.input-append select+.btn-group .btn:last-child,.input-append .uneditable-input+.btn-group .btn:last-child{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append .add-on,.input-append .btn,.input-append .btn-group{margin-left:-1px}.input-append .add-on:last-child,.input-append .btn:last-child,.input-append .btn-group:last-child>.dropdown-toggle{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append input,.input-prepend.input-append select,.input-prepend.input-append .uneditable-input{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-prepend.input-append input+.btn-group .btn,.input-prepend.input-append select+.btn-group .btn,.input-prepend.input-append .uneditable-input+.btn-group .btn{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append .add-on:first-child,.input-prepend.input-append .btn:first-child{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-prepend.input-append .add-on:last-child,.input-prepend.input-append .btn:last-child{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append .btn-group:first-child{margin-left:0}input.search-query{padding-right:14px;padding-right:4px \9;padding-left:14px;padding-left:4px \9;margin-bottom:0;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.form-search .input-append .search-query,.form-search .input-prepend .search-query{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.form-search .input-append .search-query{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search .input-append .btn{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .search-query{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .btn{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search input,.form-inline input,.form-horizontal input,.form-search textarea,.form-inline textarea,.form-horizontal textarea,.form-search select,.form-inline select,.form-horizontal select,.form-search .help-inline,.form-inline .help-inline,.form-horizontal .help-inline,.form-search .uneditable-input,.form-inline .uneditable-input,.form-horizontal .uneditable-input,.form-search .input-prepend,.form-inline .input-prepend,.form-horizontal .input-prepend,.form-search .input-append,.form-inline .input-append,.form-horizontal .input-append{display:inline-block;*display:inline;margin-bottom:0;vertical-align:middle;*zoom:1}.form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none}.form-search label,.form-inline label,.form-search .btn-group,.form-inline .btn-group{display:inline-block}.form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{margin-bottom:0}.form-search .radio,.form-search .checkbox,.form-inline .radio,.form-inline .checkbox{padding-left:0;margin-bottom:0;vertical-align:middle}.form-search .radio input[type="radio"],.form-search .checkbox input[type="checkbox"],.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:left;margin-right:3px;margin-left:0}.control-group{margin-bottom:10px}legend+.control-group{margin-top:20px;-webkit-margin-top-collapse:separate}.form-horizontal .control-group{margin-bottom:20px;*zoom:1}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;line-height:0;content:""}.form-horizontal .control-group:after{clear:both}.form-horizontal .control-label{float:left;width:160px;padding-top:5px;text-align:right}.form-horizontal .controls{*display:inline-block;*padding-left:20px;margin-left:180px;*margin-left:0}.form-horizontal .controls:first-child{*padding-left:180px}.form-horizontal .help-block{margin-bottom:0}.form-horizontal input+.help-block,.form-horizontal select+.help-block,.form-horizontal textarea+.help-block,.form-horizontal .uneditable-input+.help-block,.form-horizontal .input-prepend+.help-block,.form-horizontal .input-append+.help-block{margin-top:10px}.form-horizontal .form-actions{padding-left:180px}table{max-width:100%;background-color:transparent;border-collapse:collapse;border-spacing:0}.table{width:100%;margin-bottom:20px}.table th,.table td{padding:8px;line-height:20px;text-align:left;vertical-align:top;border-top:1px solid #ddd}.table th{font-weight:bold}.table thead th{vertical-align:bottom}.table caption+thead tr:first-child th,.table caption+thead tr:first-child td,.table colgroup+thead tr:first-child th,.table colgroup+thead tr:first-child td,.table thead:first-child tr:first-child th,.table thead:first-child tr:first-child td{border-top:0}.table tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed th,.table-condensed td{padding:4px 5px}.table-bordered{border:1px solid #ddd;border-collapse:separate;*border-collapse:collapse;border-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.table-bordered th,.table-bordered td{border-left:1px solid #ddd}.table-bordered caption+thead tr:first-child th,.table-bordered caption+tbody tr:first-child th,.table-bordered caption+tbody tr:first-child td,.table-bordered colgroup+thead tr:first-child th,.table-bordered colgroup+tbody tr:first-child th,.table-bordered colgroup+tbody tr:first-child td,.table-bordered thead:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child td{border-top:0}.table-bordered thead:first-child tr:first-child>th:first-child,.table-bordered tbody:first-child tr:first-child>td:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered thead:first-child tr:first-child>th:last-child,.table-bordered tbody:first-child tr:first-child>td:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}.table-bordered thead:last-child tr:last-child>th:first-child,.table-bordered tbody:last-child tr:last-child>td:first-child,.table-bordered tfoot:last-child tr:last-child>td:first-child{-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px}.table-bordered thead:last-child tr:last-child>th:last-child,.table-bordered tbody:last-child tr:last-child>td:last-child,.table-bordered tfoot:last-child tr:last-child>td:last-child{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px}.table-bordered tfoot+tbody:last-child tr:last-child td:first-child{-webkit-border-bottom-left-radius:0;border-bottom-left-radius:0;-moz-border-radius-bottomleft:0}.table-bordered tfoot+tbody:last-child tr:last-child td:last-child{-webkit-border-bottom-right-radius:0;border-bottom-right-radius:0;-moz-border-radius-bottomright:0}.table-bordered caption+thead tr:first-child th:first-child,.table-bordered caption+tbody tr:first-child td:first-child,.table-bordered colgroup+thead tr:first-child th:first-child,.table-bordered colgroup+tbody tr:first-child td:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered caption+thead tr:first-child th:last-child,.table-bordered caption+tbody tr:first-child td:last-child,.table-bordered colgroup+thead tr:first-child th:last-child,.table-bordered colgroup+tbody tr:first-child td:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}.table-striped tbody>tr:nth-child(odd)>td,.table-striped tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.table-hover tbody tr:hover td,.table-hover tbody tr:hover th{background-color:#f5f5f5}table td[class*="span"],table th[class*="span"],.row-fluid table td[class*="span"],.row-fluid table th[class*="span"]{display:table-cell;float:none;margin-left:0}.table td.span1,.table th.span1{float:none;width:44px;margin-left:0}.table td.span2,.table th.span2{float:none;width:124px;margin-left:0}.table td.span3,.table th.span3{float:none;width:204px;margin-left:0}.table td.span4,.table th.span4{float:none;width:284px;margin-left:0}.table td.span5,.table th.span5{float:none;width:364px;margin-left:0}.table td.span6,.table th.span6{float:none;width:444px;margin-left:0}.table td.span7,.table th.span7{float:none;width:524px;margin-left:0}.table td.span8,.table th.span8{float:none;width:604px;margin-left:0}.table td.span9,.table th.span9{float:none;width:684px;margin-left:0}.table td.span10,.table th.span10{float:none;width:764px;margin-left:0}.table td.span11,.table th.span11{float:none;width:844px;margin-left:0}.table td.span12,.table th.span12{float:none;width:924px;margin-left:0}.table tbody tr.success td{background-color:#dff0d8}.table tbody tr.error td{background-color:#f2dede}.table tbody tr.warning td{background-color:#fcf8e3}.table tbody tr.info td{background-color:#d9edf7}.table-hover tbody tr.success:hover td{background-color:#d0e9c6}.table-hover tbody tr.error:hover td{background-color:#ebcccc}.table-hover tbody tr.warning:hover td{background-color:#faf2cc}.table-hover tbody tr.info:hover td{background-color:#c4e3f3}[class^="icon-"],[class*=" icon-"]{display:inline-block;width:14px;height:14px;margin-top:1px;*margin-right:.3em;line-height:14px;vertical-align:text-top;background-image:url("../img/glyphicons-halflings.png");background-position:14px 14px;background-repeat:no-repeat}.icon-white,.nav-pills>.active>a>[class^="icon-"],.nav-pills>.active>a>[class*=" icon-"],.nav-list>.active>a>[class^="icon-"],.nav-list>.active>a>[class*=" icon-"],.navbar-inverse .nav>.active>a>[class^="icon-"],.navbar-inverse .nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"],.dropdown-submenu:hover>a>[class^="icon-"],.dropdown-submenu:hover>a>[class*=" icon-"]{background-image:url("../img/glyphicons-halflings-white.png")}.icon-glass{background-position:0 0}.icon-music{background-position:-24px 0}.icon-search{background-position:-48px 0}.icon-envelope{background-position:-72px 0}.icon-heart{background-position:-96px 0}.icon-star{background-position:-120px 0}.icon-star-empty{background-position:-144px 0}.icon-user{background-position:-168px 0}.icon-film{background-position:-192px 0}.icon-th-large{background-position:-216px 0}.icon-th{background-position:-240px 0}.icon-th-list{background-position:-264px 0}.icon-ok{background-position:-288px 0}.icon-remove{background-position:-312px 0}.icon-zoom-in{background-position:-336px 0}.icon-zoom-out{background-position:-360px 0}.icon-off{background-position:-384px 0}.icon-signal{background-position:-408px 0}.icon-cog{background-position:-432px 0}.icon-trash{background-position:-456px 0}.icon-home{background-position:0 -24px}.icon-file{background-position:-24px -24px}.icon-time{background-position:-48px -24px}.icon-road{background-position:-72px -24px}.icon-download-alt{background-position:-96px -24px}.icon-download{background-position:-120px -24px}.icon-upload{background-position:-144px -24px}.icon-inbox{background-position:-168px -24px}.icon-play-circle{background-position:-192px -24px}.icon-repeat{background-position:-216px -24px}.icon-refresh{background-position:-240px -24px}.icon-list-alt{background-position:-264px -24px}.icon-lock{background-position:-287px -24px}.icon-flag{background-position:-312px -24px}.icon-headphones{background-position:-336px -24px}.icon-volume-off{background-position:-360px -24px}.icon-volume-down{background-position:-384px -24px}.icon-volume-up{background-position:-408px -24px}.icon-qrcode{background-position:-432px -24px}.icon-barcode{background-position:-456px -24px}.icon-tag{background-position:0 -48px}.icon-tags{background-position:-25px -48px}.icon-book{background-position:-48px -48px}.icon-bookmark{background-position:-72px -48px}.icon-print{background-position:-96px -48px}.icon-camera{background-position:-120px -48px}.icon-font{background-position:-144px -48px}.icon-bold{background-position:-167px -48px}.icon-italic{background-position:-192px -48px}.icon-text-height{background-position:-216px -48px}.icon-text-width{background-position:-240px -48px}.icon-align-left{background-position:-264px -48px}.icon-align-center{background-position:-288px -48px}.icon-align-right{background-position:-312px -48px}.icon-align-justify{background-position:-336px -48px}.icon-list{background-position:-360px -48px}.icon-indent-left{background-position:-384px -48px}.icon-indent-right{background-position:-408px -48px}.icon-facetime-video{background-position:-432px -48px}.icon-picture{background-position:-456px -48px}.icon-pencil{background-position:0 -72px}.icon-map-marker{background-position:-24px -72px}.icon-adjust{background-position:-48px -72px}.icon-tint{background-position:-72px -72px}.icon-edit{background-position:-96px -72px}.icon-share{background-position:-120px -72px}.icon-check{background-position:-144px -72px}.icon-move{background-position:-168px -72px}.icon-step-backward{background-position:-192px -72px}.icon-fast-backward{background-position:-216px -72px}.icon-backward{background-position:-240px -72px}.icon-play{background-position:-264px -72px}.icon-pause{background-position:-288px -72px}.icon-stop{background-position:-312px -72px}.icon-forward{background-position:-336px -72px}.icon-fast-forward{background-position:-360px -72px}.icon-step-forward{background-position:-384px -72px}.icon-eject{background-position:-408px -72px}.icon-chevron-left{background-position:-432px -72px}.icon-chevron-right{background-position:-456px -72px}.icon-plus-sign{background-position:0 -96px}.icon-minus-sign{background-position:-24px -96px}.icon-remove-sign{background-position:-48px -96px}.icon-ok-sign{background-position:-72px -96px}.icon-question-sign{background-position:-96px -96px}.icon-info-sign{background-position:-120px -96px}.icon-screenshot{background-position:-144px -96px}.icon-remove-circle{background-position:-168px -96px}.icon-ok-circle{background-position:-192px -96px}.icon-ban-circle{background-position:-216px -96px}.icon-arrow-left{background-position:-240px -96px}.icon-arrow-right{background-position:-264px -96px}.icon-arrow-up{background-position:-289px -96px}.icon-arrow-down{background-position:-312px -96px}.icon-share-alt{background-position:-336px -96px}.icon-resize-full{background-position:-360px -96px}.icon-resize-small{background-position:-384px -96px}.icon-plus{background-position:-408px -96px}.icon-minus{background-position:-433px -96px}.icon-asterisk{background-position:-456px -96px}.icon-exclamation-sign{background-position:0 -120px}.icon-gift{background-position:-24px -120px}.icon-leaf{background-position:-48px -120px}.icon-fire{background-position:-72px -120px}.icon-eye-open{background-position:-96px -120px}.icon-eye-close{background-position:-120px -120px}.icon-warning-sign{background-position:-144px -120px}.icon-plane{background-position:-168px -120px}.icon-calendar{background-position:-192px -120px}.icon-random{width:16px;background-position:-216px -120px}.icon-comment{background-position:-240px -120px}.icon-magnet{background-position:-264px -120px}.icon-chevron-up{background-position:-288px -120px}.icon-chevron-down{background-position:-313px -119px}.icon-retweet{background-position:-336px -120px}.icon-shopping-cart{background-position:-360px -120px}.icon-folder-close{background-position:-384px -120px}.icon-folder-open{width:16px;background-position:-408px -120px}.icon-resize-vertical{background-position:-432px -119px}.icon-resize-horizontal{background-position:-456px -118px}.icon-hdd{background-position:0 -144px}.icon-bullhorn{background-position:-24px -144px}.icon-bell{background-position:-48px -144px}.icon-certificate{background-position:-72px -144px}.icon-thumbs-up{background-position:-96px -144px}.icon-thumbs-down{background-position:-120px -144px}.icon-hand-right{background-position:-144px -144px}.icon-hand-left{background-position:-168px -144px}.icon-hand-up{background-position:-192px -144px}.icon-hand-down{background-position:-216px -144px}.icon-circle-arrow-right{background-position:-240px -144px}.icon-circle-arrow-left{background-position:-264px -144px}.icon-circle-arrow-up{background-position:-288px -144px}.icon-circle-arrow-down{background-position:-312px -144px}.icon-globe{background-position:-336px -144px}.icon-wrench{background-position:-360px -144px}.icon-tasks{background-position:-384px -144px}.icon-filter{background-position:-408px -144px}.icon-briefcase{background-position:-432px -144px}.icon-fullscreen{background-position:-456px -144px}.dropup,.dropdown{position:relative}.dropdown-toggle{*margin-bottom:-3px}.dropdown-toggle:active,.open .dropdown-toggle{outline:0}.caret{display:inline-block;width:0;height:0;vertical-align:top;border-top:4px solid #000;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.dropdown .caret{margin-top:8px;margin-left:2px}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);*border-right-width:2px;*border-bottom-width:2px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.dropdown-menu li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:20px;color:#333;white-space:nowrap}.dropdown-menu li>a:hover,.dropdown-menu li>a:focus,.dropdown-submenu:hover>a{color:#fff;text-decoration:none;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.dropdown-menu .active>a,.dropdown-menu .active>a:hover{color:#fff;text-decoration:none;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;outline:0;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.dropdown-menu .disabled>a,.dropdown-menu .disabled>a:hover{color:#999}.dropdown-menu .disabled>a:hover{text-decoration:none;cursor:default;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open{*z-index:1000}.open>.dropdown-menu{display:block}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid #000;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}.dropdown-submenu{position:relative}.dropdown-submenu>.dropdown-menu{top:0;left:100%;margin-top:-6px;margin-left:-1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px}.dropdown-submenu:hover>.dropdown-menu{display:block}.dropup .dropdown-submenu>.dropdown-menu{top:auto;bottom:0;margin-top:0;margin-bottom:-2px;-webkit-border-radius:5px 5px 5px 0;-moz-border-radius:5px 5px 5px 0;border-radius:5px 5px 5px 0}.dropdown-submenu>a:after{display:block;float:right;width:0;height:0;margin-top:5px;margin-right:-10px;border-color:transparent;border-left-color:#ccc;border-style:solid;border-width:5px 0 5px 5px;content:" "}.dropdown-submenu:hover>a:after{border-left-color:#fff}.dropdown-submenu.pull-left{float:none}.dropdown-submenu.pull-left>.dropdown-menu{left:-100%;margin-left:10px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.dropdown .dropdown-menu .nav-header{padding-right:20px;padding-left:20px}.typeahead{z-index:1051;margin-top:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-large{padding:24px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.well-small{padding:9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.fade{opacity:0;-webkit-transition:opacity .15s linear;-moz-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;-moz-transition:height .35s ease;-o-transition:height .35s ease;transition:height .35s ease}.collapse.in{height:auto}.close{float:right;font-size:20px;font-weight:bold;line-height:20px;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover{color:#000;text-decoration:none;cursor:pointer;opacity:.4;filter:alpha(opacity=40)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.btn{display:inline-block;*display:inline;padding:4px 12px;margin-bottom:0;*margin-left:.3em;font-size:14px;line-height:20px;color:#333;text-align:center;text-shadow:0 1px 1px rgba(255,255,255,0.75);vertical-align:middle;cursor:pointer;background-color:#f5f5f5;*background-color:#e6e6e6;background-image:-moz-linear-gradient(top,#fff,#e6e6e6);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#e6e6e6));background-image:-webkit-linear-gradient(top,#fff,#e6e6e6);background-image:-o-linear-gradient(top,#fff,#e6e6e6);background-image:linear-gradient(to bottom,#fff,#e6e6e6);background-repeat:repeat-x;border:1px solid #bbb;*border:0;border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);border-bottom-color:#a2a2a2;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffe6e6e6',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);*zoom:1;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn:hover,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{color:#333;background-color:#e6e6e6;*background-color:#d9d9d9}.btn:active,.btn.active{background-color:#ccc \9}.btn:first-child{*margin-left:0}.btn:hover{color:#333;text-decoration:none;background-position:0 -15px;-webkit-transition:background-position .1s linear;-moz-transition:background-position .1s linear;-o-transition:background-position .1s linear;transition:background-position .1s linear}.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn.disabled,.btn[disabled]{cursor:default;background-image:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-large{padding:11px 19px;font-size:17.5px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.btn-large [class^="icon-"],.btn-large [class*=" icon-"]{margin-top:4px}.btn-small{padding:2px 10px;font-size:11.9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-small [class^="icon-"],.btn-small [class*=" icon-"]{margin-top:0}.btn-mini [class^="icon-"],.btn-mini [class*=" icon-"]{margin-top:-1px}.btn-mini{padding:0 6px;font-size:10.5px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-block{display:block;width:100%;padding-right:0;padding-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-inverse.active{color:rgba(255,255,255,0.75)}.btn{border-color:#c5c5c5;border-color:rgba(0,0,0,0.15) rgba(0,0,0,0.15) rgba(0,0,0,0.25)}.btn-primary{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#006dcc;*background-color:#04c;background-image:-moz-linear-gradient(top,#08c,#04c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#04c));background-image:-webkit-linear-gradient(top,#08c,#04c);background-image:-o-linear-gradient(top,#08c,#04c);background-image:linear-gradient(to bottom,#08c,#04c);background-repeat:repeat-x;border-color:#04c #0044cc #002a80;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0044cc',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-primary:hover,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{color:#fff;background-color:#04c;*background-color:#003bb3}.btn-primary:active,.btn-primary.active{background-color:#039 \9}.btn-warning{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#faa732;*background-color:#f89406;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(to bottom,#fbb450,#f89406);background-repeat:repeat-x;border-color:#f89406 #f89406 #ad6704;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-warning:hover,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{color:#fff;background-color:#f89406;*background-color:#df8505}.btn-warning:active,.btn-warning.active{background-color:#c67605 \9}.btn-danger{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#da4f49;*background-color:#bd362f;background-image:-moz-linear-gradient(top,#ee5f5b,#bd362f);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#bd362f));background-image:-webkit-linear-gradient(top,#ee5f5b,#bd362f);background-image:-o-linear-gradient(top,#ee5f5b,#bd362f);background-image:linear-gradient(to bottom,#ee5f5b,#bd362f);background-repeat:repeat-x;border-color:#bd362f #bd362f #802420;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffbd362f',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-danger:hover,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{color:#fff;background-color:#bd362f;*background-color:#a9302a}.btn-danger:active,.btn-danger.active{background-color:#942a25 \9}.btn-success{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#5bb75b;*background-color:#51a351;background-image:-moz-linear-gradient(top,#62c462,#51a351);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#51a351));background-image:-webkit-linear-gradient(top,#62c462,#51a351);background-image:-o-linear-gradient(top,#62c462,#51a351);background-image:linear-gradient(to bottom,#62c462,#51a351);background-repeat:repeat-x;border-color:#51a351 #51a351 #387038;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff51a351',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-success:hover,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{color:#fff;background-color:#51a351;*background-color:#499249}.btn-success:active,.btn-success.active{background-color:#408140 \9}.btn-info{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#49afcd;*background-color:#2f96b4;background-image:-moz-linear-gradient(top,#5bc0de,#2f96b4);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#2f96b4));background-image:-webkit-linear-gradient(top,#5bc0de,#2f96b4);background-image:-o-linear-gradient(top,#5bc0de,#2f96b4);background-image:linear-gradient(to bottom,#5bc0de,#2f96b4);background-repeat:repeat-x;border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff2f96b4',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-info:hover,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{color:#fff;background-color:#2f96b4;*background-color:#2a85a0}.btn-info:active,.btn-info.active{background-color:#24748c \9}.btn-inverse{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#363636;*background-color:#222;background-image:-moz-linear-gradient(top,#444,#222);background-image:-webkit-gradient(linear,0 0,0 100%,from(#444),to(#222));background-image:-webkit-linear-gradient(top,#444,#222);background-image:-o-linear-gradient(top,#444,#222);background-image:linear-gradient(to bottom,#444,#222);background-repeat:repeat-x;border-color:#222 #222222 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444',endColorstr='#ff222222',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-inverse:hover,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{color:#fff;background-color:#222;*background-color:#151515}.btn-inverse:active,.btn-inverse.active{background-color:#080808 \9}button.btn,input[type="submit"].btn{*padding-top:3px;*padding-bottom:3px}button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner{padding:0;border:0}button.btn.btn-large,input[type="submit"].btn.btn-large{*padding-top:7px;*padding-bottom:7px}button.btn.btn-small,input[type="submit"].btn.btn-small{*padding-top:3px;*padding-bottom:3px}button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px}.btn-link,.btn-link:active,.btn-link[disabled]{background-color:transparent;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-link{color:#08c;cursor:pointer;border-color:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-link:hover{color:#005580;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover{color:#333;text-decoration:none}.btn-group{position:relative;display:inline-block;*display:inline;*margin-left:.3em;font-size:0;white-space:nowrap;vertical-align:middle;*zoom:1}.btn-group:first-child{*margin-left:0}.btn-group+.btn-group{margin-left:5px}.btn-toolbar{margin-top:10px;margin-bottom:10px;font-size:0}.btn-toolbar>.btn+.btn,.btn-toolbar>.btn-group+.btn,.btn-toolbar>.btn+.btn-group{margin-left:5px}.btn-group>.btn{position:relative;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group>.btn+.btn{margin-left:-1px}.btn-group>.btn,.btn-group>.dropdown-menu,.btn-group>.popover{font-size:14px}.btn-group>.btn-mini{font-size:10.5px}.btn-group>.btn-small{font-size:11.9px}.btn-group>.btn-large{font-size:17.5px}.btn-group>.btn:first-child{margin-left:0;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px}.btn-group>.btn:last-child,.btn-group>.dropdown-toggle{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px}.btn-group>.btn.large:first-child{margin-left:0;-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px}.btn-group>.btn.large:last-child,.btn-group>.large.dropdown-toggle{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px}.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active{z-index:2}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{*padding-top:5px;padding-right:8px;*padding-bottom:5px;padding-left:8px;-webkit-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn-group>.btn-mini+.dropdown-toggle{*padding-top:2px;padding-right:5px;*padding-bottom:2px;padding-left:5px}.btn-group>.btn-small+.dropdown-toggle{*padding-top:5px;*padding-bottom:4px}.btn-group>.btn-large+.dropdown-toggle{*padding-top:7px;padding-right:12px;*padding-bottom:7px;padding-left:12px}.btn-group.open .dropdown-toggle{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn-group.open .btn.dropdown-toggle{background-color:#e6e6e6}.btn-group.open .btn-primary.dropdown-toggle{background-color:#04c}.btn-group.open .btn-warning.dropdown-toggle{background-color:#f89406}.btn-group.open .btn-danger.dropdown-toggle{background-color:#bd362f}.btn-group.open .btn-success.dropdown-toggle{background-color:#51a351}.btn-group.open .btn-info.dropdown-toggle{background-color:#2f96b4}.btn-group.open .btn-inverse.dropdown-toggle{background-color:#222}.btn .caret{margin-top:8px;margin-left:0}.btn-mini .caret,.btn-small .caret,.btn-large .caret{margin-top:6px}.btn-large .caret{border-top-width:5px;border-right-width:5px;border-left-width:5px}.dropup .btn-large .caret{border-bottom-width:5px}.btn-primary .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret{border-top-color:#fff;border-bottom-color:#fff}.btn-group-vertical{display:inline-block;*display:inline;*zoom:1}.btn-group-vertical>.btn{display:block;float:none;max-width:100%;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group-vertical>.btn+.btn{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:first-child{-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.btn-group-vertical>.btn:last-child{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.btn-group-vertical>.btn-large:first-child{-webkit-border-radius:6px 6px 0 0;-moz-border-radius:6px 6px 0 0;border-radius:6px 6px 0 0}.btn-group-vertical>.btn-large:last-child{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.alert{padding:8px 35px 8px 14px;margin-bottom:20px;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.alert,.alert h4{color:#c09853}.alert h4{margin:0}.alert .close{position:relative;top:-2px;right:-21px;line-height:20px}.alert-success{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}.alert-success h4{color:#468847}.alert-danger,.alert-error{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}.alert-danger h4,.alert-error h4{color:#b94a48}.alert-info{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}.alert-info h4{color:#3a87ad}.alert-block{padding-top:14px;padding-bottom:14px}.alert-block>p,.alert-block>ul{margin-bottom:0}.alert-block p+p{margin-top:5px}.nav{margin-bottom:20px;margin-left:0;list-style:none}.nav>li>a{display:block}.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li>a>img{max-width:none}.nav>.pull-right{float:right}.nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:20px;color:#999;text-shadow:0 1px 0 rgba(255,255,255,0.5);text-transform:uppercase}.nav li+.nav-header{margin-top:9px}.nav-list{padding-right:15px;padding-left:15px;margin-bottom:0}.nav-list>li>a,.nav-list .nav-header{margin-right:-15px;margin-left:-15px;text-shadow:0 1px 0 rgba(255,255,255,0.5)}.nav-list>li>a{padding:3px 15px}.nav-list>.active>a,.nav-list>.active>a:hover{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.2);background-color:#08c}.nav-list [class^="icon-"],.nav-list [class*=" icon-"]{margin-right:2px}.nav-list .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.nav-tabs,.nav-pills{*zoom:1}.nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after{display:table;line-height:0;content:""}.nav-tabs:after,.nav-pills:after{clear:both}.nav-tabs>li,.nav-pills>li{float:left}.nav-tabs>li>a,.nav-pills>li>a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{margin-bottom:-1px}.nav-tabs>li>a{padding-top:8px;padding-bottom:8px;line-height:20px;border:1px solid transparent;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eeeeee #ddd}.nav-tabs>.active>a,.nav-tabs>.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-pills>li>a{padding-top:8px;padding-bottom:8px;margin-top:2px;margin-bottom:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.nav-pills>.active>a,.nav-pills>.active>a:hover{color:#fff;background-color:#08c}.nav-stacked>li{float:none}.nav-stacked>li>a{margin-right:0}.nav-tabs.nav-stacked{border-bottom:0}.nav-tabs.nav-stacked>li>a{border:1px solid #ddd;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.nav-tabs.nav-stacked>li:first-child>a{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-topleft:4px}.nav-tabs.nav-stacked>li:last-child>a{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomright:4px;-moz-border-radius-bottomleft:4px}.nav-tabs.nav-stacked>li>a:hover{z-index:2;border-color:#ddd}.nav-pills.nav-stacked>li>a{margin-bottom:3px}.nav-pills.nav-stacked>li:last-child>a{margin-bottom:1px}.nav-tabs .dropdown-menu{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.nav-pills .dropdown-menu{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.nav .dropdown-toggle .caret{margin-top:6px;border-top-color:#08c;border-bottom-color:#08c}.nav .dropdown-toggle:hover .caret{border-top-color:#005580;border-bottom-color:#005580}.nav-tabs .dropdown-toggle .caret{margin-top:8px}.nav .active .dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.nav-tabs .active .dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.nav>.dropdown.active>a:hover{cursor:pointer}.nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>li.dropdown.open.active>a:hover{color:#fff;background-color:#999;border-color:#999}.nav li.dropdown.open .caret,.nav li.dropdown.open.active .caret,.nav li.dropdown.open a:hover .caret{border-top-color:#fff;border-bottom-color:#fff;opacity:1;filter:alpha(opacity=100)}.tabs-stacked .open>a:hover{border-color:#999}.tabbable{*zoom:1}.tabbable:before,.tabbable:after{display:table;line-height:0;content:""}.tabbable:after{clear:both}.tab-content{overflow:auto}.tabs-below>.nav-tabs,.tabs-right>.nav-tabs,.tabs-left>.nav-tabs{border-bottom:0}.tab-content>.tab-pane,.pill-content>.pill-pane{display:none}.tab-content>.active,.pill-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd #ddd}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px}.tabs-left>.nav-tabs{float:left;margin-right:19px;border-right:1px solid #ddd}.tabs-left>.nav-tabs>li>a{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #dddddd #eee #eeeeee}.tabs-left>.nav-tabs .active>a,.tabs-left>.nav-tabs .active>a:hover{border-color:#ddd transparent #ddd #ddd;*border-right-color:#fff}.tabs-right>.nav-tabs{float:right;margin-left:19px;border-left:1px solid #ddd}.tabs-right>.nav-tabs>li>a{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eeeeee #eee #dddddd}.tabs-right>.nav-tabs .active>a,.tabs-right>.nav-tabs .active>a:hover{border-color:#ddd #ddd #ddd transparent;*border-left-color:#fff}.nav>.disabled>a{color:#999}.nav>.disabled>a:hover{text-decoration:none;cursor:default;background-color:transparent}.navbar{*position:relative;*z-index:2;margin-bottom:20px;overflow:visible}.navbar-inner{min-height:40px;padding-right:20px;padding-left:20px;background-color:#fafafa;background-image:-moz-linear-gradient(top,#fff,#f2f2f2);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#f2f2f2));background-image:-webkit-linear-gradient(top,#fff,#f2f2f2);background-image:-o-linear-gradient(top,#fff,#f2f2f2);background-image:linear-gradient(to bottom,#fff,#f2f2f2);background-repeat:repeat-x;border:1px solid #d4d4d4;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#fff2f2f2',GradientType=0);*zoom:1;-webkit-box-shadow:0 1px 4px rgba(0,0,0,0.065);-moz-box-shadow:0 1px 4px rgba(0,0,0,0.065);box-shadow:0 1px 4px rgba(0,0,0,0.065)}.navbar-inner:before,.navbar-inner:after{display:table;line-height:0;content:""}.navbar-inner:after{clear:both}.navbar .container{width:auto}.nav-collapse.collapse{height:auto;overflow:visible}.navbar .brand{display:block;float:left;padding:10px 20px 10px;margin-left:-20px;font-size:20px;font-weight:200;color:#777;text-shadow:0 1px 0 #fff}.navbar .brand:hover{text-decoration:none}.navbar-text{margin-bottom:0;line-height:40px;color:#777}.navbar-link{color:#777}.navbar-link:hover{color:#333}.navbar .divider-vertical{height:40px;margin:0 9px;border-right:1px solid #fff;border-left:1px solid #f2f2f2}.navbar .btn,.navbar .btn-group{margin-top:5px}.navbar .btn-group .btn,.navbar .input-prepend .btn,.navbar .input-append .btn{margin-top:0}.navbar-form{margin-bottom:0;*zoom:1}.navbar-form:before,.navbar-form:after{display:table;line-height:0;content:""}.navbar-form:after{clear:both}.navbar-form input,.navbar-form select,.navbar-form .radio,.navbar-form .checkbox{margin-top:5px}.navbar-form input,.navbar-form select,.navbar-form .btn{display:inline-block;margin-bottom:0}.navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"]{margin-top:3px}.navbar-form .input-append,.navbar-form .input-prepend{margin-top:5px;white-space:nowrap}.navbar-form .input-append input,.navbar-form .input-prepend input{margin-top:0}.navbar-search{position:relative;float:left;margin-top:5px;margin-bottom:0}.navbar-search .search-query{padding:4px 14px;margin-bottom:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.navbar-static-top{position:static;margin-bottom:0}.navbar-static-top .navbar-inner{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;margin-bottom:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{border-width:0 0 1px}.navbar-fixed-bottom .navbar-inner{border-width:1px 0 0}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding-right:0;padding-left:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.navbar-fixed-top{top:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{-webkit-box-shadow:0 1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 10px rgba(0,0,0,0.1);box-shadow:0 1px 10px rgba(0,0,0,0.1)}.navbar-fixed-bottom{bottom:0}.navbar-fixed-bottom .navbar-inner{-webkit-box-shadow:0 -1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 -1px 10px rgba(0,0,0,0.1);box-shadow:0 -1px 10px rgba(0,0,0,0.1)}.navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0}.navbar .nav.pull-right{float:right;margin-right:0}.navbar .nav>li{float:left}.navbar .nav>li>a{float:none;padding:10px 15px 10px;color:#777;text-decoration:none;text-shadow:0 1px 0 #fff}.navbar .nav .dropdown-toggle .caret{margin-top:8px}.navbar .nav>li>a:focus,.navbar .nav>li>a:hover{color:#333;text-decoration:none;background-color:transparent}.navbar .nav>.active>a,.navbar .nav>.active>a:hover,.navbar .nav>.active>a:focus{color:#555;text-decoration:none;background-color:#e5e5e5;-webkit-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);-moz-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);box-shadow:inset 0 3px 8px rgba(0,0,0,0.125)}.navbar .btn-navbar{display:none;float:right;padding:7px 10px;margin-right:5px;margin-left:5px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#ededed;*background-color:#e5e5e5;background-image:-moz-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f2f2f2),to(#e5e5e5));background-image:-webkit-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:-o-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:linear-gradient(to bottom,#f2f2f2,#e5e5e5);background-repeat:repeat-x;border-color:#e5e5e5 #e5e5e5 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2',endColorstr='#ffe5e5e5',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075)}.navbar .btn-navbar:hover,.navbar .btn-navbar:active,.navbar .btn-navbar.active,.navbar .btn-navbar.disabled,.navbar .btn-navbar[disabled]{color:#fff;background-color:#e5e5e5;*background-color:#d9d9d9}.navbar .btn-navbar:active,.navbar .btn-navbar.active{background-color:#ccc \9}.navbar .btn-navbar .icon-bar{display:block;width:18px;height:2px;background-color:#f5f5f5;-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.25);-moz-box-shadow:0 1px 0 rgba(0,0,0,0.25);box-shadow:0 1px 0 rgba(0,0,0,0.25)}.btn-navbar .icon-bar+.icon-bar{margin-top:3px}.navbar .nav>li>.dropdown-menu:before{position:absolute;top:-7px;left:9px;display:inline-block;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-left:7px solid transparent;border-bottom-color:rgba(0,0,0,0.2);content:''}.navbar .nav>li>.dropdown-menu:after{position:absolute;top:-6px;left:10px;display:inline-block;border-right:6px solid transparent;border-bottom:6px solid #fff;border-left:6px solid transparent;content:''}.navbar-fixed-bottom .nav>li>.dropdown-menu:before{top:auto;bottom:-7px;border-top:7px solid #ccc;border-bottom:0;border-top-color:rgba(0,0,0,0.2)}.navbar-fixed-bottom .nav>li>.dropdown-menu:after{top:auto;bottom:-6px;border-top:6px solid #fff;border-bottom:0}.navbar .nav li.dropdown>a:hover .caret{border-top-color:#555;border-bottom-color:#555}.navbar .nav li.dropdown.open>.dropdown-toggle,.navbar .nav li.dropdown.active>.dropdown-toggle,.navbar .nav li.dropdown.open.active>.dropdown-toggle{color:#555;background-color:#e5e5e5}.navbar .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#777;border-bottom-color:#777}.navbar .nav li.dropdown.open>.dropdown-toggle .caret,.navbar .nav li.dropdown.active>.dropdown-toggle .caret,.navbar .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.navbar .pull-right>li>.dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right{right:0;left:auto}.navbar .pull-right>li>.dropdown-menu:before,.navbar .nav>li>.dropdown-menu.pull-right:before{right:12px;left:auto}.navbar .pull-right>li>.dropdown-menu:after,.navbar .nav>li>.dropdown-menu.pull-right:after{right:13px;left:auto}.navbar .pull-right>li>.dropdown-menu .dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right .dropdown-menu{right:100%;left:auto;margin-right:-1px;margin-left:0;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.navbar-inverse .navbar-inner{background-color:#1b1b1b;background-image:-moz-linear-gradient(top,#222,#111);background-image:-webkit-gradient(linear,0 0,0 100%,from(#222),to(#111));background-image:-webkit-linear-gradient(top,#222,#111);background-image:-o-linear-gradient(top,#222,#111);background-image:linear-gradient(to bottom,#222,#111);background-repeat:repeat-x;border-color:#252525;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222',endColorstr='#ff111111',GradientType=0)}.navbar-inverse .brand,.navbar-inverse .nav>li>a{color:#999;text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.navbar-inverse .brand:hover,.navbar-inverse .nav>li>a:hover{color:#fff}.navbar-inverse .brand{color:#999}.navbar-inverse .navbar-text{color:#999}.navbar-inverse .nav>li>a:focus,.navbar-inverse .nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .nav .active>a,.navbar-inverse .nav .active>a:hover,.navbar-inverse .nav .active>a:focus{color:#fff;background-color:#111}.navbar-inverse .navbar-link{color:#999}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .divider-vertical{border-right-color:#222;border-left-color:#111}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle{color:#fff;background-color:#111}.navbar-inverse .nav li.dropdown>a:hover .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#999;border-bottom-color:#999}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .navbar-search .search-query{color:#fff;background-color:#515151;border-color:#111;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-webkit-transition:none;-moz-transition:none;-o-transition:none;transition:none}.navbar-inverse .navbar-search .search-query:-moz-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:-ms-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:focus,.navbar-inverse .navbar-search .search-query.focused{padding:5px 15px;color:#333;text-shadow:0 1px 0 #fff;background-color:#fff;border:0;outline:0;-webkit-box-shadow:0 0 3px rgba(0,0,0,0.15);-moz-box-shadow:0 0 3px rgba(0,0,0,0.15);box-shadow:0 0 3px rgba(0,0,0,0.15)}.navbar-inverse .btn-navbar{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e0e0e;*background-color:#040404;background-image:-moz-linear-gradient(top,#151515,#040404);background-image:-webkit-gradient(linear,0 0,0 100%,from(#151515),to(#040404));background-image:-webkit-linear-gradient(top,#151515,#040404);background-image:-o-linear-gradient(top,#151515,#040404);background-image:linear-gradient(to bottom,#151515,#040404);background-repeat:repeat-x;border-color:#040404 #040404 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515',endColorstr='#ff040404',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.navbar-inverse .btn-navbar:hover,.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active,.navbar-inverse .btn-navbar.disabled,.navbar-inverse .btn-navbar[disabled]{color:#fff;background-color:#040404;*background-color:#000}.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active{background-color:#000 \9}.breadcrumb{padding:8px 15px;margin:0 0 20px;list-style:none;background-color:#f5f5f5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.breadcrumb>li{display:inline-block;*display:inline;text-shadow:0 1px 0 #fff;*zoom:1}.breadcrumb>li>.divider{padding:0 5px;color:#ccc}.breadcrumb>.active{color:#999}.pagination{margin:20px 0}.pagination ul{display:inline-block;*display:inline;margin-bottom:0;margin-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*zoom:1;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:0 1px 2px rgba(0,0,0,0.05);box-shadow:0 1px 2px rgba(0,0,0,0.05)}.pagination ul>li{display:inline}.pagination ul>li>a,.pagination ul>li>span{float:left;padding:4px 12px;line-height:20px;text-decoration:none;background-color:#fff;border:1px solid #ddd;border-left-width:0}.pagination ul>li>a:hover,.pagination ul>.active>a,.pagination ul>.active>span{background-color:#f5f5f5}.pagination ul>.active>a,.pagination ul>.active>span{color:#999;cursor:default}.pagination ul>.disabled>span,.pagination ul>.disabled>a,.pagination ul>.disabled>a:hover{color:#999;cursor:default;background-color:transparent}.pagination ul>li:first-child>a,.pagination ul>li:first-child>span{border-left-width:1px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px}.pagination ul>li:last-child>a,.pagination ul>li:last-child>span{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px}.pagination-centered{text-align:center}.pagination-right{text-align:right}.pagination-large ul>li>a,.pagination-large ul>li>span{padding:11px 19px;font-size:17.5px}.pagination-large ul>li:first-child>a,.pagination-large ul>li:first-child>span{-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px}.pagination-large ul>li:last-child>a,.pagination-large ul>li:last-child>span{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px}.pagination-mini ul>li:first-child>a,.pagination-small ul>li:first-child>a,.pagination-mini ul>li:first-child>span,.pagination-small ul>li:first-child>span{-webkit-border-bottom-left-radius:3px;border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px;border-top-left-radius:3px;-moz-border-radius-bottomleft:3px;-moz-border-radius-topleft:3px}.pagination-mini ul>li:last-child>a,.pagination-small ul>li:last-child>a,.pagination-mini ul>li:last-child>span,.pagination-small ul>li:last-child>span{-webkit-border-top-right-radius:3px;border-top-right-radius:3px;-webkit-border-bottom-right-radius:3px;border-bottom-right-radius:3px;-moz-border-radius-topright:3px;-moz-border-radius-bottomright:3px}.pagination-small ul>li>a,.pagination-small ul>li>span{padding:2px 10px;font-size:11.9px}.pagination-mini ul>li>a,.pagination-mini ul>li>span{padding:0 6px;font-size:10.5px}.pager{margin:20px 0;text-align:center;list-style:none;*zoom:1}.pager:before,.pager:after{display:table;line-height:0;content:""}.pager:after{clear:both}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.pager li>a:hover{text-decoration:none;background-color:#f5f5f5}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>span{color:#999;cursor:default;background-color:#fff}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop,.modal-backdrop.fade.in{opacity:.8;filter:alpha(opacity=80)}.modal{position:fixed;top:10%;left:50%;z-index:1050;width:560px;margin-left:-280px;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,0.3);*border:1px solid #999;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;outline:0;-webkit-box-shadow:0 3px 7px rgba(0,0,0,0.3);-moz-box-shadow:0 3px 7px rgba(0,0,0,0.3);box-shadow:0 3px 7px rgba(0,0,0,0.3);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box}.modal.fade{top:-25%;-webkit-transition:opacity .3s linear,top .3s ease-out;-moz-transition:opacity .3s linear,top .3s ease-out;-o-transition:opacity .3s linear,top .3s ease-out;transition:opacity .3s linear,top .3s ease-out}.modal.fade.in{top:10%}.modal-header{padding:9px 15px;border-bottom:1px solid #eee}.modal-header .close{margin-top:2px}.modal-header h3{margin:0;line-height:30px}.modal-body{position:relative;max-height:400px;padding:15px;overflow-y:auto}.modal-form{margin-bottom:0}.modal-footer{padding:14px 15px 15px;margin-bottom:0;text-align:right;background-color:#f5f5f5;border-top:1px solid #ddd;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;*zoom:1;-webkit-box-shadow:inset 0 1px 0 #fff;-moz-box-shadow:inset 0 1px 0 #fff;box-shadow:inset 0 1px 0 #fff}.modal-footer:before,.modal-footer:after{display:table;line-height:0;content:""}.modal-footer:after{clear:both}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.tooltip{position:absolute;z-index:1030;display:block;padding:5px;font-size:11px;opacity:0;filter:alpha(opacity=0);visibility:visible}.tooltip.in{opacity:.8;filter:alpha(opacity=80)}.tooltip.top{margin-top:-3px}.tooltip.right{margin-left:3px}.tooltip.bottom{margin-top:3px}.tooltip.left{margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-color:#000;border-width:5px 5px 0}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-right-color:#000;border-width:5px 5px 5px 0}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-left-color:#000;border-width:5px 0 5px 5px}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-color:#000;border-width:0 5px 5px}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;width:236px;padding:1px;text-align:left;white-space:normal;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;font-weight:normal;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover .arrow,.popover .arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover .arrow{border-width:11px}.popover .arrow:after{border-width:10px;content:""}.popover.top .arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,0.25);border-bottom-width:0}.popover.top .arrow:after{bottom:1px;margin-left:-10px;border-top-color:#fff;border-bottom-width:0}.popover.right .arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,0.25);border-left-width:0}.popover.right .arrow:after{bottom:-10px;left:1px;border-right-color:#fff;border-left-width:0}.popover.bottom .arrow{top:-11px;left:50%;margin-left:-11px;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,0.25);border-top-width:0}.popover.bottom .arrow:after{top:1px;margin-left:-10px;border-bottom-color:#fff;border-top-width:0}.popover.left .arrow{top:50%;right:-11px;margin-top:-11px;border-left-color:#999;border-left-color:rgba(0,0,0,0.25);border-right-width:0}.popover.left .arrow:after{right:1px;bottom:-10px;border-left-color:#fff;border-right-width:0}.thumbnails{margin-left:-20px;list-style:none;*zoom:1}.thumbnails:before,.thumbnails:after{display:table;line-height:0;content:""}.thumbnails:after{clear:both}.row-fluid .thumbnails{margin-left:0}.thumbnails>li{float:left;margin-bottom:20px;margin-left:20px}.thumbnail{display:block;padding:4px;line-height:20px;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.055);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.055);box-shadow:0 1px 3px rgba(0,0,0,0.055);-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}a.thumbnail:hover{border-color:#08c;-webkit-box-shadow:0 1px 4px rgba(0,105,214,0.25);-moz-box-shadow:0 1px 4px rgba(0,105,214,0.25);box-shadow:0 1px 4px rgba(0,105,214,0.25)}.thumbnail>img{display:block;max-width:100%;margin-right:auto;margin-left:auto}.thumbnail .caption{padding:9px;color:#555}.media,.media-body{overflow:hidden;*overflow:visible;zoom:1}.media,.media .media{margin-top:15px}.media:first-child{margin-top:0}.media-object{display:block}.media-heading{margin:0 0 5px}.media .pull-left{margin-right:10px}.media .pull-right{margin-left:10px}.media-list{margin-left:0;list-style:none}.label,.badge{display:inline-block;padding:2px 4px;font-size:11.844px;font-weight:bold;line-height:14px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);white-space:nowrap;vertical-align:baseline;background-color:#999}.label{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.badge{padding-right:9px;padding-left:9px;-webkit-border-radius:9px;-moz-border-radius:9px;border-radius:9px}.label:empty,.badge:empty{display:none}a.label:hover,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.label-important,.badge-important{background-color:#b94a48}.label-important[href],.badge-important[href]{background-color:#953b39}.label-warning,.badge-warning{background-color:#f89406}.label-warning[href],.badge-warning[href]{background-color:#c67605}.label-success,.badge-success{background-color:#468847}.label-success[href],.badge-success[href]{background-color:#356635}.label-info,.badge-info{background-color:#3a87ad}.label-info[href],.badge-info[href]{background-color:#2d6987}.label-inverse,.badge-inverse{background-color:#333}.label-inverse[href],.badge-inverse[href]{background-color:#1a1a1a}.btn .label,.btn .badge{position:relative;top:-1px}.btn-mini .label,.btn-mini .badge{top:0}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-moz-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-ms-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:0 0}to{background-position:40px 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f7f7f7;background-image:-moz-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f5f5f5),to(#f9f9f9));background-image:-webkit-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-o-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:linear-gradient(to bottom,#f5f5f5,#f9f9f9);background-repeat:repeat-x;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5',endColorstr='#fff9f9f9',GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.progress .bar{float:left;width:0;height:100%;font-size:12px;color:#fff;text-align:center;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e90d2;background-image:-moz-linear-gradient(top,#149bdf,#0480be);background-image:-webkit-gradient(linear,0 0,0 100%,from(#149bdf),to(#0480be));background-image:-webkit-linear-gradient(top,#149bdf,#0480be);background-image:-o-linear-gradient(top,#149bdf,#0480be);background-image:linear-gradient(to bottom,#149bdf,#0480be);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf',endColorstr='#ff0480be',GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width .6s ease;-moz-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress .bar+.bar{-webkit-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15)}.progress-striped .bar{background-color:#149bdf;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;-moz-background-size:40px 40px;-o-background-size:40px 40px;background-size:40px 40px}.progress.active .bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;-ms-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-danger .bar,.progress .bar-danger{background-color:#dd514c;background-image:-moz-linear-gradient(top,#ee5f5b,#c43c35);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#c43c35));background-image:-webkit-linear-gradient(top,#ee5f5b,#c43c35);background-image:-o-linear-gradient(top,#ee5f5b,#c43c35);background-image:linear-gradient(to bottom,#ee5f5b,#c43c35);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffc43c35',GradientType=0)}.progress-danger.progress-striped .bar,.progress-striped .bar-danger{background-color:#ee5f5b;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-success .bar,.progress .bar-success{background-color:#5eb95e;background-image:-moz-linear-gradient(top,#62c462,#57a957);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#57a957));background-image:-webkit-linear-gradient(top,#62c462,#57a957);background-image:-o-linear-gradient(top,#62c462,#57a957);background-image:linear-gradient(to bottom,#62c462,#57a957);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff57a957',GradientType=0)}.progress-success.progress-striped .bar,.progress-striped .bar-success{background-color:#62c462;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-info .bar,.progress .bar-info{background-color:#4bb1cf;background-image:-moz-linear-gradient(top,#5bc0de,#339bb9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#339bb9));background-image:-webkit-linear-gradient(top,#5bc0de,#339bb9);background-image:-o-linear-gradient(top,#5bc0de,#339bb9);background-image:linear-gradient(to bottom,#5bc0de,#339bb9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff339bb9',GradientType=0)}.progress-info.progress-striped .bar,.progress-striped .bar-info{background-color:#5bc0de;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-warning .bar,.progress .bar-warning{background-color:#faa732;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(to bottom,#fbb450,#f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0)}.progress-warning.progress-striped .bar,.progress-striped .bar-warning{background-color:#fbb450;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.accordion{margin-bottom:20px}.accordion-group{margin-bottom:2px;border:1px solid #e5e5e5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.accordion-heading{border-bottom:0}.accordion-heading .accordion-toggle{display:block;padding:8px 15px}.accordion-toggle{cursor:pointer}.accordion-inner{padding:9px 15px;border-top:1px solid #e5e5e5}.carousel{position:relative;margin-bottom:20px;line-height:1}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-moz-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img{display:block;line-height:1}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:40%;left:15px;width:40px;height:40px;margin-top:-20px;font-size:60px;font-weight:100;line-height:30px;color:#fff;text-align:center;background:#222;border:3px solid #fff;-webkit-border-radius:23px;-moz-border-radius:23px;border-radius:23px;opacity:.5;filter:alpha(opacity=50)}.carousel-control.right{right:15px;left:auto}.carousel-control:hover{color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}.carousel-caption{position:absolute;right:0;bottom:0;left:0;padding:15px;background:#333;background:rgba(0,0,0,0.75)}.carousel-caption h4,.carousel-caption p{line-height:20px;color:#fff}.carousel-caption h4{margin:0 0 5px}.carousel-caption p{margin-bottom:0}.hero-unit{padding:60px;margin-bottom:30px;font-size:18px;font-weight:200;line-height:30px;color:inherit;background-color:#eee;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;letter-spacing:-1px;color:inherit}.hero-unit li{line-height:30px}.pull-right{float:right}.pull-left{float:left}.hide{display:none}.show{display:block}.invisible{visibility:hidden}.affix{position:fixed}.clear{clear:both;visibility:hidden}.clear hr{display:none}.section p,.section p,.section dt,.section dt{margin-right:7px;margin-left:7px}#ohloh{margin-bottom:10px}#poweredBy{text-align:center}a.externalLink{padding-right:18px}a.newWindow{background:url('../images/window-new.png') right center no-repeat;padding-right:18px}a.externalLink[href^=http]{background:url('../images/internet-web-browser.png') right center no-repeat;padding-right:18px}a.externalLink[href$=".asc"]{background:url('../images/accessories-text-editor.png') right center no-repeat;padding-right:18px}a.externalLink[href$=".jpg"],a.externalLink[href$=".jpeg"],a.externalLink[href$=".gif"],a.externalLink[href$=".png"]{background:url('../images/image-x-generic.png') right center no-repeat;padding-right:18px}a.externalLink[href$=".tar.gz"],a.externalLink[href$=".zip"]{background:url('../images/package-x-generic.png') right center no-repeat;padding-right:18px}a.externalLink[href$=".md5"],a.externalLink[href$=".sha1"]{background:url('../images/document-properties.png') right center no-repeat;padding-right:18px}a.externalLink[href^=https]{background:url('../images/application-certificate.png') right center no-repeat;padding-right:18px}a.externalLink[href^=file]{background:url('../images/drive-harddisk.png') right center no-repeat;padding-right:18px}a.externalLink[href^=ftp]{background:url('../images/network-server.png') right center no-repeat;padding-right:18px}a.externalLink[href^=mailto]{background:url('../images/contact-new.png') right center no-repeat;padding-right:18px}li.none{list-style:none}.search-query{background-image:url(http://www.google.com/cse/intl/en/images/google_custom_search_watermark.gif);background-attachment:initial;background-origin:initial;background-clip:initial;background-color:#fff;background-position:0 50%;background-repeat:no-repeat no-repeat;width:95%}body.topBarEnabled{padding-top:60px}body.topBarDisabled{padding-top:20px}.builtBy{display:block}img.builtBy{margin:10px auto}#search-form{margin-left:9px;margin-right:9px}.hero-unit h2{font-size:60px}tt{padding:0 3px 2px;font-family:Monaco,Andale Mono,Courier New,monospace;font-size:.8em;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;background-color:#fee9cc;color:rgba(0,0,0,0.75);padding:1px 3px}li{color:#404040}table.zebra-striped{background-color:#FFF}.footer{background-color:#EEE}.sidebar-nav{padding-left:0;padding-right:0}.sidebar-nav .icon-chevron-right,.sidebar-nav .icon-chevron-down{margin-top:2px;margin-right:-6px;float:right;opacity:.25}li.pull-right{margin-left:3px;margin-right:3px}.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0;padding-left:15px}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} \ No newline at end of file diff --git a/dependency-check-gradle/css/print.css b/dependency-check-gradle/css/print.css new file mode 100644 index 000000000..1cd02d9b4 --- /dev/null +++ b/dependency-check-gradle/css/print.css @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/* $Id: print.css 1201871 2011-11-14 20:18:24Z simonetripodi $ */ + +#banner, #footer, #leftcol, #breadcrumbs, .docs #toc, .docs .courtesylinks, #leftColumn, #navColumn {display: none !important;} +#bodyColumn, body.docs div.docs {margin: 0 !important;border: none !important} diff --git a/dependency-check-gradle/css/site.css b/dependency-check-gradle/css/site.css new file mode 100644 index 000000000..055e7e286 --- /dev/null +++ b/dependency-check-gradle/css/site.css @@ -0,0 +1 @@ +/* You can override this file with your own styles */ \ No newline at end of file diff --git a/dependency-check-gradle/images/accessories-text-editor.png b/dependency-check-gradle/images/accessories-text-editor.png new file mode 100644 index 0000000000000000000000000000000000000000..abc3366edad864f1c06e1354c2f7cd0ee1f2a080 GIT binary patch literal 746 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh3?wzC-F?i!z!(tV6XFWw9$CP!U~&MEL_-~2 zturUYuc~G2k7NQOAQwpPnVm8{M-46l)ZW(7+}_y&l!c=+t7L#iU0Nn~YlG3l-F|15 z@P0VoetaRz%cI#-`!i3iRywta^WbvRtIMVKukt^?RPfMZskwP_>zl3S&Y%79fJLFr)R5u{`~pcwQJ|jo!h;8_nch0Czn_4o{=~$Tdkui?!}82 zPoF-0^5jWpw9vyV8+S~Jn~|&5P#DqD)^z{={fV`486gG>yE10vs7-0jnK^T2duMA= zxOS1hU{#Kw#hCr%tWa%9@{DF+T5IJs^5$&)9i&zL%I{+xaL_HEjdBN!3HH6)q7{X9{`;59Zq8_K&a?NFvhbtJ!a#ML1s;*b3=G^r zHn%V%!>lqE9PESpH$neQx=aVO*B2%Y?K6$dU zvO@Al$kmjqrY2jrl%|w^{UQ0|3oj3EZ%?m}Pw82fGm<}abk?qEJm7ZynqNRiHh(Bgn?ad9p@g!lX0?hAY$6qZbCW z0lmYZTH+c}l9E`GYL#4+3Zxi}3=9o*fylrz#K6+Z#K6kbLfgR5%D~`Tz=gvo8glbf ZGSez?YiQ@qs0V6b@O1TaS?83{1OS^WRoMUl literal 0 HcmV?d00001 diff --git a/dependency-check-gradle/images/add.gif b/dependency-check-gradle/images/add.gif new file mode 100644 index 0000000000000000000000000000000000000000..1cb3dbf936e38b5c5efdc3e247a042eb1b1d23e9 GIT binary patch literal 397 zcmV;80doFFNk%w1VGsZi0Hrwqfq{XHjC_`scb}hfo}Qksu4?V%HuUQ#_Ut72?;iT^ zBKq(m_wPpc?_K-yJooTv`tnWp@M`+UP{`_CX>@2HM@dakAa8CUVIWOmV*nxf1OW;FKL9KM0000G01yBG z28=)gU`QMW1_i@!3CKC0&ddYCI52ah&u7HtL@q0qBk^l$xg^p?lB(HEigIo{N|QVi z)(zKM$kAyhAQ&1iFcb)XbtESzDjgOT6Af33jV>-IB_SdLSAi#(F{3g$0H2JZE~KTW ra*U!eGBdQMSC^|Yvokcda+j>Uy{=7A#!jw6Max43OV7~J&_Mt@cAw$D literal 0 HcmV?d00001 diff --git a/dependency-check-gradle/images/apache-maven-project-2.png b/dependency-check-gradle/images/apache-maven-project-2.png new file mode 100644 index 0000000000000000000000000000000000000000..6c096ec0c7d50ecca14e76dd49b1fcb9382c3d07 GIT binary patch literal 33442 zcma%iWmKC@v~G~1r4*-l3lxV^TvMPp!Ci|x6qg_^6n8J~65L%%(IUk)1d6-6g&V$g z?zw;Oo0XL}qtEQwduF!G)BMvvz-u`vSt$S#G5}zP_yC>`0C=C>Ol`dYNB~s8b0XmB z2=GeG%+bUgVD<}R|3Aq8??L(B=YOgrBOxJj5#RsK`2T%*`USwl02m-O zpdjG^knxaE@Q|K*k@64#(U4J)5I_I(pktuDK*dDCLPi2$Ba+cj5Iz6jJOCmK1sxd! z2@`;Y{ThIbgo28Mg7S<784c472^j?y?*%^ETXceV01Qq-v5&Mwm@4AL#&ldHs!rcY zP2%V!a%)cBb30?b>7L+WSXJW9pp2}XwvMi)m9>q#ho_f!P;f|SSa@Pma>~!tw1UE-;u1({eM4hYb4zP) zU;n`1pP}iQ*}3_J#f{Ca?Va7di_5F)o7+3Yz>!dpQBhG|prWFpp}nw2K*mFTi~oWX z4e*XYOa=X;F`*NN_;=bkBGp_IVlK=Yy6y=H=M$3E0B-ttHB!^hr+KySdETh=N}4fX zxdbLixjy67Fn81B`w{dX;BzLj#De5Yq|!iK(?%}YjUEen44;N+sl{@JZ7OOKG0 z;--PQ?Q0orE6>oMCC!8LJ2wKdI@VrcsgRaG3%j?>f^xbx-r;GbtwW1@cTbCemx$>> z#zVma00GKszvAH8G!z8CYMubb<#?A5;5p@EDiKjN4DBa?-B;0Q2Ufiu)PN=Mwc(z2 zaS&P|aB@%I#qp%sajZkx+wG_}m)S3}%+_!trkHpm%l>$pDiaK$lQ16nrcFGxhw2|) zEP6fHy7q^lVHz6Y`-$%ffG*Lh97L+J?b zkwrlysJ<(1n*HS;hP-lEi#>T?I53>941Sm!Fy{~fPF-cd- z!AHLd!=+v|zM$T}zc$?G=00!fY}E6$!-}~gA@1lv6wCO%BEeDOtIfsP@dTKyzCP-h z9yGCd;ozTZOa3U@j*Y0cCsUa6-TC**_{u)KAWHvH1W}DfbtuOO4pPO~x(3R}AP~6L z{B6|GWC1VtQlDOz;wpAbSK;a5S1Mgr122>xz$=D(pT7>S-O0P$bujnDE@wSM%upM( zWv{w~iBWuIm7pGI-7&0ybSSCL603oEo&X#4GZ*l}ppJX-%Pzb}@8q(#wKw%ofJ%A) zn159rR@9;$Yrra<N)m^7|7&3bzC?-l-X0kQs42|Lb&YNR9BBbk6xR?VCS4v(3q( z-+kz4c>*B)H)dw;FTUJ+pVkhJ&~M1!l01`YI;(~iLZNadAlbG3Sh=-~nEQC$hQ5tt zJ-iE*Ts!|+0PYE*+?*{6pI~a}*2vIY*W{e-$}Mi_QVjz z{dpTv2yJT9m2Qphua!gyD(+1-VoF|8$;I64t(^IHxgE9Pj{srYk6jO94C&9D@H06l z!Ft}mJPO|PP3bxRZ2Ac>;Qj=FI3l>1FJ%2F7T;@a_1klcZcCm#ZTlcT}Gz}2*EgP0V`_`phpC+)ANZgQJ>xS#q9e;Nm&sKJSpPk_WNWY4maA z{1P2k3nV^UY!2uT1)ux^?_8eIn!4M!9Qn7Cj{BFC1^Gk2k3A1}`|$u;9ZTY5LV;lX z${)V|bz@V{GeLMifccp5muhRaL!S-&1OPFlKg%<4!U4kuCMn_|Xdu<|`BXnWW(T)5 zMXWcvoYwT0>-#V6$-7Is{voQEmqb(RXS|ib(iiB9S{;os^dX14;@V4tVD*c(2ngQ+ zh%}pecNXsnpfNF27UV0_{U+ayS9m_~Fnifu`ZNYQ8NA35%OY$?6eLEop_xS0g6e00 zsSd+c;X$oOa~1KDy}W&4%gM^l-U8jUPX1J`!r zmCm3JGEK=y0i$-(&GOhq{>8c**DX$PbyztoZiBwJ4K{gM>!Tp?RDYJn6Cix&J!JVt z*g*Y4_)^q@4( zccLJrAK0*N>xQ6gGEt zxGC0hSYED^`}=%Ye-NHDdURA^_3K24>4=bg<@yugXAh456{HX-cI(*mEWIO{Epsap z9Und+i@cK!nTr_}sX|D470>~(zqYhjH*IIL{(Az%Owu8yaYA!JK$kW8-;rFquRc$r z24z=vS#If%Wu~0+#d|@BnM619Z^yC!*2%qYKmH2_%j1_oTL*oI@llPnk1I4_zhYcH zCAs&(wNWmolcTKc@sJ5BMXb_|$Nix-pEwTKP6K{X)YhV)BZH`(Rp7x5`u^412P(2Zv;4x{_5mg+ygb-JR z(1YjH_X)PI-jNrb=7`-`8XLps|Jy3{wcPA-?D)3mD=v{`)S;)opZ$P62vJZ?@wN*s zr(16BfwQTXU35*w=Rc=PJhQH?DcCDZGXGvrI3xs!( zY$J;504LFYSpbgOt$`Cpr#E+T&%5Lt?+VQK%d3L{eSe*bNB_kR#MU!>kC4R&|I;he z3t#Tr*}0iV9;00Z87fetFK!RmrTelLalofKT@`RBXzbn}ynFl#_j(nvodLJ^nUBY^ zzW_wpu2$}`GH-wtl?I>IS6Wv>(C^RTAH5UPueT3)fd>^=(3q+>I48JMciM2oapbvy z?FX~VM0bX|yXD8Zc7EVW{^Q2wpgZnZ5id1in`1U4fwn`M zm-bO3^!li2wHy9Oear@TD6BH}xeeWY0+=h+XYc+gTYd>#HoLAYTkV5CP**zDNH!%nyT`rnh<; z_xp$*gpNcL%4(!7t1$2hmyJ|7_*d1R8+K!qQDsHXT7w9wqNT=ej?bFjd|o(ufP#$* z8z0|^v5S}aT)A5kX`vE`{)iWrFsB=t%_0wF+B6|N?Y_c;2|(?jMS9kh#H(;3OAR(f zL5bJ8Nux-6N*hY%j|11#&Ji{nu)HULQ%CCWl3-$Ewck~rB8)V@2$C}2%db!bF*(lJoqJ>G*%Qf(9P#+tl)9+GM<=^nMc7^?3N>XU6t_9uW_6-+5nokRGzZEIIpk$7Fc$EGIZ^)%pRwCU1&oYdUU4iuwrt@X`go6kKAH0rV)nm4r{+xfbt!t75qK?k#rHLOAn8`# zxN#}pdGXvfr3zBV6kb@!EC4tbTRlH=dHLy@GmtIo?M&&WsO zd*~ajK9*SEIq3X#>rY<(Lcb?XOINdyC0`<4=C!ElOC8Q4e zbmLp_%oJHjSe2;?ltK)@yQxFOD6TEs*8(w`kNP(LDodQ3G@t z6Y8^Od%GqPy-bLs5XVc4gfS8(2}iTA`-y)O(sZb3r6V$^2}(b_?xH(=bE~uLhh)vT z8>G=6Io|+$zW)*JAc6J3fFrmYqZ)d0~-*U>h<|1+C{G-Sss~R z{hsc12~>~0i-r2|@yI5=GCu2#qy~?|bx|a2<{wwlo#0f4tK2aj$fAb7bE=^d3^pOD^^~{h19S4y zOi?NHsqu7Ln6&qN$N`y@hXdCZD+EbwtY^qpuLy79@)B2BWem4*7ao3Y1Lx`s2EO%o z1hj3Ud=JqFhUH6Bj*m@R>E8}BluV8VDZ3WyxyW??aC$Bkt&AcVxgtmyncvFBTDxEU zyfdsx50KuP3-7m7gI`$nT+LlYmv^~8e1;qP8k||$`{*p)R3*KEEi6pWPkdkg>1}Ou zH&(^sQhz#rc<^d>nXtY_;XeE8X1*6>gLH4iO;CNR(C8ZqUDkm729#IZp)WDmh-gZ)m2T;`H&62y)dLQ*CHxCBM(gjfJ+3sdO&pA(o&fK6q{yqCJToU!M-Cqx zR!1ei!BXW6s&ph12PUTl+1#ZtPrXPtT;#d&dzW_)dn_9CKDRdFOO15Pby1|@R?lt! zx^*?>1NN^3WRqVvY5F)H@8QOh=hu5A561{~fV-+bXehfj_Wv1^jZ;^M;4zeD2`wI+ zTQgVi6;!q?jFiRJlEs(7xK@&FvTJl`OtEK()+}sBf;*6Q-(K84)N|f4gEAi`ypR3S z5Vjkr@mjZ?=szgAkejh>8$sEb5K1lGkV7eDZY#b|$r8VULKtCv7(wsl-Y#a^`=}L| zNWG*(<8>VRjIEpvbx&cb-?$(vknYaEl5gPb9`*#_^doXzaW!t*HaKqQof>lO8f29u z6zXzS)^s?ms;^Drp6@7Z=HhnMP*FX)Q<&lTEWkwLjZqw}O`APM(kkZGba-}H;cr@Q z^##MmlE&vzY`teV-?7o}wQGv1sh{Ab(x74K?Th(GD9n{mY%6Tl`?`fA z!dMIwxJzsO9t@q&C^T9eFnDK9pE32vKut+nYK{MKvTy!?2Cv(-PNX+ON7^P~&l4a5 z@&%#m-aH(1KkVG3p2gJNDSh#==)Zo|v)JNI78SQZTF&dvy#!Sg2^nyp-~kzMlSkzi zkE}y#jm!-pMZnI&pZ%!jBKJA7>lStn%Zm+we|G`QK;i9*3}7O)^;OJ0ZKjwWEE6R9 zYY7VNxbEy3u`k)#%a1{d98|F=JrQVal^aT1$Vy;I?w?W-VAt?F;Urc&hP`Zjg9cL>V+Xicdh64+604+1?lPwmCJGK`1BniHv^gPTivIwO?JL;rjZF-L3%t{H;C6 zZ{o!@ab)u5Fmv73a`av36k1?9YuVkir5Rf(88S*bc z9KMsVTVAwu1X^&G$YlH$zrgbkcQbAvMtpAYI7W}${8DMaF*egs~5ING_9pGVk#MwHB44HxE5w0xvtvg1vS; zAJrz3WuZsKLDpv0zKRw0_1eSh`q{4+`uo(`bs%zCRF)yQ*{=e-lCr5h&=wX~$c3ub zjno_&_TdW$_8m1s5~Xdn_AjOF+{)i5B)NV(VloYGpPEwX1BH|Zdlv9SP#l7|xyD|6 z(te!Mf=aeZ6U{U>1WRLSRR1o%{VLk|*=c9Pfg}0}K)`D`*pB;Y`>NRe$ZpJ1jiQpo z_20=n=Uk=-fvHUtJGsXZe{s>DvCO46tZoYRhf0xahW!VL`k)s00zA1MVUT~L$Mwi#hA zs(BQf&6w7bcd^9v82`l-5^|Q$l&iVnvC=|Ysty&))?J?)Dxz!lLVBN=fg#k;J9LxuSkTl%kuN|3bu%%Wd#gC)UERV zP4>i`F@%HWuJn>Vzs?7ctpqKg25fUMhHAk&>a(i*iB_SA8YY^-BP;I&J7dJEpf{yi zQae*A$Fatf$nRxzxDAP%)zDD?d`v|4ne7;+eAuQD=`_$>mmc;4?8*29Fg<6ODi`rT zz3vn&+ipPXDOw8S8^|1;g+{pBI}9&sKeh#|{9MebP)wH)V4Y5-a5GmR`d|}Zlomu& zT9ihDOu|71F1ByXwQj>O@xbFYPx=mcOv6?1($a>g``UcOD?#`7`_1Fu1ge^FazDC+HQo?~(?Ax-5}kiK8p5bIOq^ z>ukT*b5aVxu2bUquy2%XtM3|l%Xb>sZdP$~-rC7*x_hc8(bB|DVtH&(2m`BOzB=Et zd8n`89MfWF_V)Hk=Aw)&EVEf8^xBHn6;Z$B;hfG1gzM8LF9 zHOTwpZD-02tl^r?NdD;MwUx5NB2Ik+5v+@ypsIhQa0%bk`t0?T|Eur--2q4vvqT|d zPCOFnhX%{6zrItG^LENIc77F^rv_+tAV zG8(!3H+kPvTbL$zWcY0s6hhNODmZmgHM7#ulcA7kh!vMN%iE;A*CotZkCW-7R~HLg zn(X7j`ElFgjGCRF)ndjfoUf6e0NlKz8&8052cm`g0##+Cvso!tzSr}t zH@PxgCn_=qX8|?R#3DTb(4)otfK>>Cb33p9xp4*_F+l<6R?nrfU3jxrOinw}BSJL} zx}rXJp$Nx~A$oUL$;jJ5ySQ>ls7n8w#m*M=u*givl)sBb0*8R=Y~Ia0$|g{hYavu` z1KHWGQ5a}8Kj%I5H%9k(IrNK`K7RCPqrH2F@dJ$EBIbfcQ7f70)sU+#9FTxHAd0X7 zeTRntGo+V{Znot-eFCSh^hhKx$YZmAx#>Ou4E?nbNVC!82rlAH;eA~@$B4E(9;B!* zUHqFI?}QMY>Zi~W-B`ywB-%d#7@n;HvT~EXyK;?BfPeu`gtjg%da1HM*XmRl-C7f% zrZP9uyNhH3xqAZqkywt%S(Egxmf}arb+Nm+I{B+MnowHEZ^uT#p=FdZJkoq%|AInp zj7P)V*KB-pa!P`fby8-i^u-^P1>e8BmNw|2dzjorv<%}ucf3$uwkh`(c~B>&MQdC@ z>AMsQy73npsPT#bK*Cfsv46yIRM`-45ERimN20>UtC?=Rsd$3wMs0>R~i`HXY+NmIm9c!Vf%;U#1x*INc?($IfkdnS{o~21B0!#D?JKCZ~Fwu z_lw!Pu|j2@{?kn2yjA?AqF}nhOyJ-p&v;wQ26kJ8jn3FjN?CG+9@pX2@}Al-bAXAsA#-5Zen z&&rg>FvxZ(4dR_y(GjiwBf%Qrn_a#0m9(QQAs>&hB#il$@X^On@(;;rowfBmNAVn2 zYD)(h`(HPkS~h)?Rnbb^ew}ju!;A|2m_@U9``TyQ$kuO-+ASK?+`3Q*ZG@XT;uJJC zw}V5E_o)YPL)LkIW(jjjHHy&;5gk!#6>T5C+_GfIfW?|qzxi1i+Sg1wpsB^itBXnU zxmLYLO^rYPO}MVMPO5rDMN~}9(da?uumSWiJ&mU?bA}8%1SwVffvy9I4qvD_)+N9@ zbD$+7WT-uUHXXlP=@LM8G zATt=B19S+bQPuG21GHF4#Ix1SvgNUj(!qnT)bG1sN5me)K{r)xsV>*ALBxNtoEON=9`EpYMC>wq!4y7r$^7}2tNzf^P7DKbF?9C3q`jHi@H zQ1GPc{hY75iIskjK+nNE{XqYCs-aB2-OLx8TM=3@{=9m>_v?yF$kl!mY6)_m{(b!#4ti0axo(E6Gb z1b6aVztcI5Hjn0wbBKy|hsLlvavAFO0%6{Ry6;9LJar+3Kk=5L7JHRH(2Se81+REH zS_l-+Q@b7spq;5OM|iToHGfcE`b;M`?IYvXJ3rhn(}QJT_yicdGThvk8|_&f_YL+S zU=v~0i_fwlBQuyBrH(Gl?VT8Vl?o{`5VxX{vo;0mQ1QOhaWc1Tg1xA<$z3bhd)IeEfqg1d8e6>WYk75aaYL7mFW4omO09OR);%Gr9|N|~zRERUAN{y)AD~HBTq)lD z9ZfrSzPfwsS~}=cxKACgXSr^#Xv%6Ov~TO4H43K>DeB%>9nhTAa%g3BH?aOF9(P(@ zB$pN+LA%a{ix;(uqS0|*Cc0_gJYc6k`ADxDPGM25O=ScWo3OF-+9OG@$Mkd`$Y!uDh3ftXXT?*H7n8?(LZ9CulsiRi|FmV2h z7EXRE#`6wamG4VDHzVyoPqlb>*z64%9OqQj>D=7x@U{1IbVKnuS)C{)R$85HJHqeG z+FLAi#K#LU(UQ7p)NaG0xp$cNyW%M+0~c1qKTH2?3q| zmBd$8(#D05tLYdRysYzLIO(Gs!E3j|xb&8`Z=RRN*{~7jNs^Jw1qOvsOcvbTUVNL+ zgw=dC!fDfkIO~KrH^H|LUb=%Zqu`VYX<7LsFD&(x=qAlgi?|6#Y7Q5BayPU@IR`2n zj}o9OdPSo=>16uc-@Z%yhHUo?Ubqu%R!Ltaz3PVvWw(N9Aza$JpFykDjT_{p!iH;E z+_I%6`q9gMnt5s<-8aT1x}nS0OF4lyGDtwxIY$q-YQgCCPFiKi{f@_hXG_WCGc(IJ_IXWWDHrd+NWHI3|6IZja+_-BgR!{^&xRL?kf zrc;9uw#zZj)Hj%VD(<>o7f~vlzBP~Mjcl1S&|f*8j*~Sto+i5Jb1KvBZ=zRisZlu+a!CUN)VR@TSrcQ_nnAiGI!5jl z*!x93nYWGce>WFD^q21I27J0ez4fO4;GMEWc|7a(+HH1uQ6y#F;D?h?I&LPctTfHPke_*6dnh9SmnQPc~r3<{~Zv=2>S~ zfAO9x*MoN5?Q@;=SX~8kebofjILUv%zncgjl78nKMQO&P>olg&P`ewi(U@p&gg8WN zktda>Pa4t^IMhRO&(NCJXViT%4@6ozJ2f6MU_zP=`zJcSPk?$GD;vuIZ@x61o#pbv z*akLL31LCYqAw^V@8|9i?8XEu4&Q^zuJS~M=B{p_XKRwrKAu-^-lS&kElD|aAslc4 zN1(L@VOPR8f>!^$A4gT%koyu(=m|^bqxwJ$c@o1(k8;1j!-Y?Pb{cZBg)(XguCDUQ zv=S91QXrdfgOv3e#KXfPZo|Ue!-Dl_WJsQivxOnvcRvsRKu;@MYHpL`>p|zAK|8Xj zbS<642=vAk$^`40hMTK^isGOjHVyUT^*wUgsxbe7kCT!b*P-ugA;VX=>?eRZJ zhmO%A=P`@mh{n3~1T%-nHo4}5N*`~<0d|{Tv`!(@k5r?k9cW| zS~-!4A1Q58TQ#FT#}qq^pHKsU^!!!xo-q>Rsk526@YGIeWe1#^?;~mlpxnCJd+!i> z6*2Cw?eRZSOIge`;;~4|<0WO@TJ!wO*QDY4Sk2=@Zf&aUBH$Sq38xa^+=o2C% z60`#5!h&_o>J7L!P$r;B_&Y3h!j|v-u>R~Z1{say1CL)1qWG)UCvvz>ky)U5xUnowL26QxOk85Wxnr@#^U8*T}SF! z^Yfwdi?T_fHeSma_hj1-dGHpeooi*329SJ-EzWg4DL!?2f>$6iAc>Du6yB-37 z&#nD66y+J(zr1|iwGZbhoCM`BCA|gT_0uWc}3mJLxnrdG3yZijs zoU*TbLxoZ3R52X-4@Lu$lJY-SIJA&Tf|zrARl5naWEBnR&u3({czA*2O7}T?kTf>a zhk2KQ=D;N-uUjr?nJ;*A>}K7E_!Jj^6>j^QCJ3IMB=?V#f5&5ZDW=8IOxRkceWALm z{=%4U?=d6*+VIBCQdiVnkjz&7F-uW6^5U|0IV;UuDiB+R!VOES|J=7Z^QhYE+srYM z2S=ym=HG3~tl@?MRMr8$gx3bPpN9YCzneM*ob5j7`fNGqURj#8FPTDbgRkWI3urt8 z-mThhNlFmimN48glsX@;Y_YZ8ad^(yM^Ykl z-^;=MF=*v!%W{9Bxu@>3ed8xaxnVji_Ad;8^6*?S)JE$Wx$EP<2B+=kHSUVkElt5> z`M4mFm;Cn7PR`Tu0r6k58j(ePC=$U{1G5k+U2B?T=Ad^ELC7kbSrXPwGA(+`V5_4> zXncJOmcNop-beviQ9|GP7BPniVg0neLjUq#w277=o%6y0sv@-wHX^G&VEj zrmr7=-48iyY)#eNj~?=Ul&E%r&wYr#x6JY<6%JFHtJTC^*ZJE8)g4rfl?#MOYu9!$ zx#JkndE0PJX(^UYJ^^qL9(mfBtct!xU93BO*I1d!rD{gGYT@&-=3$$w`xGxnzjz_} zFb~Qo`T`ee)CQ}u-_|)ENWq3=-*byqJrI$!o>gyMx|sBC@RqwrYx`ebxzEjJ_cK#8=GY^ftr^GSrYYYXUIuXp`=nyk+k{~z~Hz8_rnqg zuk+E!)gRPdS-MzW2%!xiFIKO5;vxVGzbN3_7fP2i`LBaBx1+a>jbWt(5^;HpKf`QG z-v^YQp~*U9?If|0Hcy&jyf`k)Hot-fugz*g*;hLb8+mz0#BW|>z7easqXqPOIsGaW zyxeY}_CB)g=-Bd|`WoWc+@(88SsRZvA}pTsAupW0SnzKKBBFge;wA>okcrvj@7}Ur z&3brR!ok@an>0b4$apVfY)Pr1aY=dnvm(nDx_NC}bD?ccu#A1}o92di& z!=?#xTbmyV*p1bmU&kAiA%*$jayti--1Mb;!czoV`0+y&*6(^<4(6<{o1kpb7KZwZ z6>Dkpf^DtA^bs0Xhgydkg|=|2BHzFxoHpkNVrW?Sq!2j5G7X5sBcJ=zQ{iAWO2_8K zM}DWB*$e4@*q;u*0@8M3KDM8bK#Zra-8{lG7nkvLZNd4}_y&1B|5UOn z6@uhP`utXzjIl{)7^A;R5(PjwIT=+vVBS zfie%YTl4Iws3$+>geFGQQmVe-9UrV|kB=){=TbP-Zm446%+8Z4Tce`1F>U5I-936^vsBg;s$ITM(9>SbSY=HN+CI5Fq^Z0rcfW>Ep4 zrB;AsArQzpWbC%}_Vl`L#n1m5n(g4*v%O!~ymEv``^Y~@niotzMaU^hiWQf4vNj?w zR42qm`1kCXa-uUYnqt#+hBGfQS^#76dr`bKhQV7$x+$R=;X2Ou8wm${LfUIKr(c+E zaoKZ+BX+k5V-qIHaS3&NvV^G8j0LdnO>nYhEH(vjHAUufW72U?h|&tEjm>$Y0wl!oi9WihF<1{|bZYjzm?URwoCXr}gK zFi9w=mby-V74=2&%q*j{G&=g*T{bK$Ci!jDzM>{H&&C{*;^aX2>!aJ*MDJE-mYkrz z6gsAwnu_3nGO=b+P@LbYnUQPUml=oinjBRCRl)RBOe|_b_S@~L=(~m8np#gEHYtt$ zIwB!8I|tTF#(X(R=q=k=SRfD$Fw!t%(pnUV6I;N;{uzfzJ$|ZQESGh8fA00oOX3ET zaHYZO3jVEc;U}Y#oZ}5qH+`_A#QD24J9emXq8%%@`V3|Itnvo=+m_SUmb_WS3i|1N z&fL%l4^tar1w&q$O6Gm!C5WzLRbZ zsjJrGC}d7Yy5DuRKyIqVQ^h*oWzCFd_$GV236EOA@*!Dan;#kxy8tD6KT@E3$CD zRr1v7aUbgP!*vms5ELR%LHmq9z5u?md9ik=P6m@Z5 z5ka1J2he|Cx(^bxEoyDBE-H6gANNhqU($1QGP|mDBu;#Dz^hw~8K0L{6cxlP7Y%_} zgwFP<(4$tD54!%1Z-15S=KO>6TDCwsT!Jtlo++1_^L+L8WJfWjsLes7r;&GrQ~}3N z+Edx`OwYTFsEZd(2}uuBU!%6oCtyD%-C_>azUnq*GD~(+(IQ&MI^CCjXL&9EYQ>e( z1WBHsP9-sVLi1=wOsv27A=9{UFKYs_tZJuSay4{By*fYAfv@iP_+37Hbp4#O`#qU& zT{ANutG3ASgN}{z?|LF4oPxR!8qu0cZepfir#uOb@V`Z0Bltvjb6Tqo*)ea2c zUsF5!)S~)LIXz!yx!~w7RE#!Mdtqht&leY$Eorw?(Q>Bc4m&6W6DQX)Kq4q#sP)o+ z`hAphUm77FgHw=$2celsB&&LjL{mfMieA`wziWS6S393ZrmHJ5C)@1e$=2{4(rezh zsVG+lY_6I1qEIAfYI15>YSgkf`zWjKH_ICEX@;}k?33ozwUScP773SVvFMah|?z#tubQy1PEK(KS>X9bg&Z@j~Cp_a8p{exayZ+3(c~5 z8HGB1iAUEjV;)&n(%jXm#Et*yQ*!3-oB&dasqpv@V(9$4w|CcmYW6-3C;YmuJ?5_j zc7Jbw_-OIAV0cCZjhZDE8fLig;6TEuN6;s)rv@ToJ!8Ut+qweNUew3<(dVx)HKG}U zh^PCege-|G2l3`>V!EcXw4GkR>Z3Asn8eEb-QXKGr)=7IFP~t?^ByRWZa?|8*{;t| z8N+&~)H1x(UTl^N?+kpcNZEKGH~u;oZWbX{Wna#xgzKj~ZH&!l$Xj_T%cVshC;6npMjROTWPn!PJBdef zzcV2)cI~pp&Be&M+C9e$>FWGuVv=dou6ydL4!6oEO9d_2s)ixvGOC3^{)S8H=6PQ) z%~x^V7CIpaMJKpwjVRl|-tp$$Zr9|$Q-qRK<&R(fFxczgjsD>H>?sV^Yye7hJ;Y|m z6i+|LV886}KND*39!5%pw(;@*ETw4Bo73R$HQp3L z?K2er5LCXoN5sHZjm99;w`4_#2unWX#ZM@Y&Cg0=+;vj8WEm1Q;vSd?!Yxa0%TV26 zy7GVwee9^R1tYF2X=PUYG-(7LHxOZep_>K(RK3sC;~j?fGbddj0X_2s6@6Mzu$e|%;lHN&0SYf{}@H<{>?m57Kq zjoBtxN}HKJ%q*%f8Z*=+H?f+y`AVfzZ(0AaPH$dz)lgUgZ?{Y$>8+m9+N72Bww$YN z9mpPSm9R;^5@sOJW?h1!%Ce~v9pi^v>Crob)6Ce$1y-J%8`ID-ira5xYf_Qc5-yaj z`lC?}j&UisjuewSGeZwI6XPr<$R^#gjg0zHosF|8*#bYPSb2rT&Ts9U zc&E)_WjNh85>4a1ZD#vUj10D_#jC&TYj4$?|8+FDd<5J7Nv~>ymZv+6xtPC*L{Y!? zfd1fh=lxLUZ|fvf?*{B4d<)wR%At2_xdoo`wF+^#NYAH-tT%lmP<;-Kfu=`{P2JxA#5&?othjSm!o&Yq?Q-@C474Y>kjoD2% zi{uk2>0Y+HX#VxjsHgA6J?npLm+xOq&HJ~u;5IlIt}PsqgrmqhzS_GwfepPtnsjgt z^$b_l3)9RD&m;_A3FP5d=qF}9RxEW;xWzlPFTZz=*Dv&m*Fjx>89S=>g5u?;$3CfP z5pO$tCWdACM0Va|*gae0QlqlP-ffQ5Tj}1Cg96LD_Zeumsv--W+eRK0S`X(QF12Hh zW=YZWwZ0$grlsk-V`FKJE*P~_kEpo;REZi!#9VETOpl{6R#Tf`ly?es%BD=5w>FWI zvj<%p%70{~P8itb%blQVu{ro_zT3PNYj-%4|McuLqAW^lzLWi)Dm|r(eY33A7bHVj zmKAi53rk<1QoEWw2G3VE?sr;ux$AJ4X(wZ=+RCsIeZ!Zf^pwI1dsY0Uq-+l2Cpveq z`16BTq=tbzm~~=mVqA=2S$)=vlvRB`T+l$njqvXXQZngai8KDY-*YOX{$QNzOb^CN zUZq!4ruEeM_(gFs7dp~t-agD-Q&0D?U~A2O$STI*+SX`;+kzYr;w6RVmdYDC)Ea_ zU>jkdpBbNPAl1Qng@!cjznnk2xg9$SpBtPmsrq(bV0j+IGt&5xx_yW4s4JgRbAbX= zMK>SHYL{f$Z-?XT<5~oZo13B$af!m3APaB{a7A-mnkEYHN@G4NXlP}#;jAc%vBW7; zsJYfFtvV()_uH2m{tWRM?@@Zq-6gL`Ub4JS@OR~lT6uY7oOhOvxi5XD{(>K;WQDby z^m2Pf?hMr)bg^wPcPk^8xjo1_6^M&lwPf=H0s(!i&Qy;ixuzD zf6)b()yqjmtPYSd$J3Qfe13cC|Lknn(0EOF`P0f&c&eRMxfSD2mL+$4&XH6nIQ zTH}=qQ(GOjP<@`YMNu(s!DGjSj3CsvXem8Kak#^gJo1`Lv@9ZY=+jw%%|yx6+whN! z#S&rMv(Y?MHErp@4w4o7{RAbZ!!dhXFP1=&Yo8Q_xa^6hKovYaJ!z0GKCg%K$mIAg zvbmAJvHK5#ao1~uL*Ed>8j#}Ud^l;aMIKfNz7mdhF!#0Ne;ppHo7T4Ok;B*2Y$*on2MQdWe{XNJ|Q z@JGTQ`o89tn#+4|QR@bk?f0v3^6X1Zlt+J+=PlKzXO6<&oJx%GU$Qq@tIZ(F`J3c4 zjVzv6mVzMcoEa0G&L4;i-)e<{xU>^deGkFQ_4g^bt*@|c|M0TZ32D`Xu+_}-{!dR| z8PL@K_Kk@Of&n5Rpi7@Ahph#=V#;#Gd(U+ z*~8u`$hX zFgLRIsAlrc38A-hJ3U&fZUc$EYcua@7&e1eS9i*DXRUKA5`~zrm-JXUq;P$$;FrDX zG15)0i+>Z~vMZ9Vyc-)Gwis70|J z$H!qszUxObvowQJLM@`k&unHIp)}vV^s(Aya9Cd+`-|Q!WQVEp3&h^yw_)l~qQ<^> z1)B{xS9U4sk6B1XxbBg!{xa>_7+gJ?5x-N>jZQZ1b+lE~Q8X-A_6_R_yPQSxorDCv zo0OoRqMr=Jo@`hM5Hc#Jr`{og!V2k#?w!2i?~77gzwfk5QJA499J54D4V-r9?3q*R;_tNaNCcJa#`EC%{`@rl5`n{X+^~?o3e*ojmGJ+5Ce>tj-p(sv}njD6;|sHQI0o0WXjr%t$ zZJa_-Qh7si@JZa}=bMvj$q^1x_8OcUdEbVu^*7KIOY`*%wbjkwU)Snhj4WxDn1 zCBd$|d$2X7IVo7JcO+p}?6l*JE2IVX_1BuHmvKOgPPGVyj+353RLOkmdLygKCjzUm zz*oD%f@`-)qh6Lg&Bc#?omWldlKOS~7Ryg=2eVtNmG_m$Nx~=?1b6mg#Y^hpeK!25 z26khXo2RFvv%k}8RScS4tHj6|yNZ=@j1sXtA@jd?#-p?Ii)BTWIcLwmR%qAT$Hl|C zcavf62^{2KLvsrA&6h}YG&vvg4;kld9v!0i5_XlH2R{uidj}58riM7+N1M)oA`Z}u)_1R=UO_ zILsh)Ygg48KJT-r`1Y>7@u+T%gPxl1qw%X0B===dW8;?Ic{B9L3Q>^N+jqrXr_%Pd zfnc!Z`)ct3Gn;j@F>FShEZN=;+~P|}P*z2bjxJr_(Y@X*W4}0Co!yMu7L9@g$7tR7 zYU<0``X#al1ylu@1!ut{phnRUc8}eX{`$q+8fv`DbK+@7GU$6MO93tF*^l2I8eI)y z*2+7jscrQLv6r;ZFxJtzk5%(4<2f@7pEYab{2RiV)-s-cNALrc=lX1}WkD}cjmo}q zuxBPZTDQqLs-e`%crRsRQFEBBR7(3~(Sn*)fyV9^;a?95>MrB#L(5vsbz+)mAfOud zFjb3_ASBZ{2rzxj2|RooUC`;<7bF%$+iSp@p`PtI6oG;Mh$7~?+J1RlJnb6~ntBW^ z>&hmYQ(`$muV@|02y}`}8e2IQ_*TH8$}@^LtX8$fdqtwxFGx&?_UIe?NBqaX+Hp2A z{y-M+^1|jIVrOe!HOO&)>t67Qvm>E-*XZNQd;?mCI*a|}Rp9pzTY-U1xBtZqfBbl( z_f`|6RM!fuIR_5`%)GiG?rzE-#Rbsa664rHpdJ@e`}N%PQa3PpjE2zY{URgwEgP>3 zl1xKlYmidcbvjV78&eNHQFP-Rg(J4S_(h%=9V|>A1$yuUD8tqu?u0z+*@@*Eb2x+) z+kFK%40TY~5*Cc9&dcm-)>wUf4o394+yIsUBX(gh#z8BejFQ}Ih6THxJx!IE0-~OE z#9j`?KX5UB*Pbdi(%hm|Yg2YQ%_KZ{2r&mv`cBR8P)TUD5j5y@PSZ|0D$c*)Wv!&Z zA8se9yqK|@fvnW1*9P8q1IQI#@!`ZX#Hs1=&tI6teeG>`q}4|dI?(4#~bs$%@LjWTDEpeK`zy> zH6I6R#EdypqB5uiyMfCY{-_aA=jZxo9HMYU^Ha?{SpxE>3RQWx?R3<-;K1|F>N^BZ zC+`*a(+Pz;K%V!bOFNS@CHhH!CXwml(ZwbXj{Rlxk>|5~)Ho67vejfx?LZjrTy3qz zwHwZZW~hyPze*^?#h*3*oK$R?$eVXaqw-K-Tk+(3AjPK9J7=Z{6t5y8-z;i#6_pS` z#;=56;BZ6IKMedQK#IxTO+oZ7#djul>y$nPy}Xsh7l1xa%?Q=_MOB~TA9 z!deaWe?QQ=b6*$W%{LDsLIIz_gvj=8qrm}?xQ#MuU7x4$0|H@|EIwW^Jh8Z2d%C=a zEwyy*dnF|z{23*d!Ei+8Uq2O{axebNNH`M#fimSGJQ^_tTp(K#Uf26fnD#_KcxOHM z3f>M31}Iou$IE;utQ|Y5NIKPvwmlSM-qDF9vaukZWjjG4XU>D$S2`!M&X&C|ZxUKJi6e@? zuzg2)RL>DXsL>+SUy#IoChqvtPD{;gY<#@c!Exl%4j^Mx4^EV8w@h9LS9mAS9@iD; zR86L4i#9$VQ8Kw2E~_Y#Kzg%|t8fdE<%jy7Wz5~YpmR6u+P7XV7MXM%v$<|tmuW$R zU&i`rZZGjc^^zn7QoOULs9MKW4B*@BOr*_=~tw}`%XozRu2SXBYQNea}kF=BZRK;?vcI}ZKcbz z4ubeBMP}m3{#`i^fx5g(|43oU^$lS&@9$7xZ`-5Y_B^Bv;aBrII!5V%3{|2t+fU&L z7?E0Kf6SS^hpz2?VOqhN!wybb&t%pKz?3L&8k6TNHv1h{-pQLs9ZF~8P&LGZm$Y(} z*rHdc-J%DDMA;tPUwbFtqw_fQ$hYM^3dNbX;cE(^d8c?D|vP2vL8w~31#-0N5g_bMghY0V&rgOSvLT64em23PN>^isyifNKpK)1VxJu(6fs($q zbK7mFtm=hWc9ok_iqB$#Z&rK;oXfx;wy;2F>py5|B->PdzvW){G>U^LEYvPY6zM@7 zpvA#jpKBf$Bs5vmZa)`sYh~Xp<~>ePKx?IdR7w|)a%>ILz5^Epbk?2Ycaqmi zq`f{b{f8u-YmeT0jJ${b9wVyf;-bm}k-CiRO^DpHsP~s1i_S#5|MMZQI9g_39-oL( zVmkc%tgia!xS|YK(LZ5n1Z@-&xvHYA8*{}cpXwe-9ocEV5()7b+zC6{*XsS!S>h?4 zW|Bl*5v%(Ui_mO6Cng)Iv)g`s_Ps}l*6=T9p+i2Zh%iK*lTsQYAzozvCSNFsw$N^= zSEuPm(Sr!vZ{?RJ;6No&V_@P-kf%9y=%p08mt@bhdnl1^y3c{}{xz+7jEs7&J+8;? zVs!O$LC_B~)}Q##R}1S{$fAiGC>Y%dd#x938=q}sZQy}$thmZss3uTgeUE3`h4){f zQts{M`%laB3nE2qB=UW=|%2)6SG4G6Y%dZ04(gMyVlk&;580%(9vZ;W0d{O?k z^iWPpy~AVU!W3hk`iYn^oqmqoiQ|ciY1IRcKXks7r$E)$E}%31F4DbILh>{K!AHe0 zEwjtnO)B&~g};*9g&YN9!QY7qWX0Vj{5Di+wrIOBCDzXtn7C`khWZcUuc1CR@VsI= zyFpyz;FMTy5M9U|eSRl*rA{WT@Q;Laj@38@s-MsF3N*@y+Ho2@X&9?Ptu*%{^J$7N zY6M^r!n~x%m{P%OW~{Iy&C6JCG$@Ad$!T@Hd?IDiB44WAGdHf+9qvO`6G0W@f_5sah|#75$I+ zUBZ!BK^gfj5nH7W4SjB)2&u1mAwe>ZvHQjZAQVWPCM*9-!k)s!l83ZwhsLd#Jkb1r`Hrl9)OAJI_CzEzE@Kfs=mHWc|Y-W zBDM!bFLBlWuCcNv?TB*D#~yON6QW#j1;bM9EK#=fwdIO_4ZmGd3r#);J@PMH+=-Y} zU2jMA5^n^$-QsNXJuhi@q5U?iwG)6d{MaUdeoS*$uw?n{aM%ekD=^3mU7cvDt8KYo zuNtd8G0g3$XGDi6>M^LII`(`vIeCxd$VdKVH$&Cuh?h9v?Em`B2nl(n1_n%;dW@}B zcuw@{>F8V)cGpt~o5kARfBC52^&z5rOyQpWm634&XrdZgt*c|nL&WKf$g>rfe5&|! zaOiqfh~kpKSnY@|)PlGOI7*~N;ufcI^YbD#9fM0g`#wvCGSp-MlvZ5&7oa11kxdy% z*!0xhj*jqG5GG;2sm5jhr5v5}$zJ*0gRY!Zvi}B(1m=1^A(t6y0D=W<<@qIPO#WEgPcjd*};rqM3RcA5DGc}?-u z{O&=yqWj(Q8z)+K348ycv?)&{Rg88!e}3-Cuof-TPyQl;gM_|>iZ;*A2Jy^AW_^y- z$V;?TGn6)9XpvJ9S*+H$a5c}9E4T|1BA-lYRk{vpPz6;as;EhN6E1zbiit^%DAT~) zhc*$Zzjh|6BZNZ@^8B8PkRSY7=y^vJKS{Mz6-*RMJgJJ?v5|I`QC1wZ=1P`y?;rZ# zr~A2BwDSwDnoU#=xx3pl579`7@p8p&j!J=Yj)#)6n>T0ZPraT<&wZ|)n{9^;PY{pc ziPi68a~8{}*W}y5__nt}Fgkev`+t}QIwBGoOu)(1JM`g{R=Jnw)g^v%CCyL44sLw* zq$|Wp%5KNL%;6~cZUWCl)`eSqJbr$iXvYGQ)r~*xzQIeimezTk;`P&W2*er6ivJLSj>{{~te1yXKn|I@D8$EXme?G+B)ioOLm3pmWXC!l=pt|u_oOy`I z!jf09ikvs1LfH#GG0`&}-5nEe-tmY0yde1p9h}}8OZdeWNLK4b!De05Bz3io|4@$a zLd%F)SR47uvcMtkv!K3yTaijo;KHK-xHhN~Z4U6x+S(N+CA~F>_S7oJP(0gm3c1w> zeopR7MgQIKM6#7<=h$TE0-tc8d|L1-OPE7|$p`spf5^;#Gnaz-P1UG1^P`$($m6cX z4SXsQ7J2%bN$XciHaMRKG)ahaWNA&;lYwD+x{(eeRwhulA~U ztN%KmP*K*?dz{*cjvVmXH|-Wq5l zmUHkh;4?wGujRB`ay}@cd~{-DT4iJ1f6eCOv+~jq?a7}V;b?VLE3U5Y&)RALt^D+s z*Eg$_d1}QWn-=*lzL3+6hvH=kkMu2{744I|{mguGQpxeLQ!gc800ZP{G*sSu^Zc|| zTSm{wBKECrGC$S1z5RQehYk*MuiCGESKPLYE93Q<{xED7#;ici zcyl=-P1!WZ`9(a_OGD%)1YnvNv*Cn?P61z@#NLzE;lJO<#n}<@NXUmhly+blMX%Zk zXd01oBK;{Py00aYMaE(xReH`;JJk5*^=^{8YQLEk;$^E>OtE>)c*zn>yx)leQC<@a zo3vJ3Urt#ZFge?+0xP?foVF^vZY?jxSuak?TmPFpMQt!nl}$n?zAw~*BQZ1=dk$yL z(M^(%V3dnCiV;cf3;y{Z&5WfeZH`k?tENs}-5<Qdz4l=qM)Kt+bLm1(^pEpmZ7g1@mTK! zV)_vvN7c_x$Eh|UEj*i!TVEcYIp`mL5u-Jb2-T28s`AAMvE(LnglvVk$ADTYbB3ckc97FGB zl}IToVdb{Pym~m=%QZdeOD9(Fyo63D2x84_ZNmeeRB#&HtN{u7BGGPoelyH@?Lv0L>sPacieH{z{!iXya(TK)B#9X4 zC<};t#6W86ug0>eXIe);U2IH~XR%5(4HEGhckd)>)mXB62WarffIzYtIJ!@MtVO=4 zZ?s$Oi`{5)?o=r#SGI|J6Ai(jfsTeiDuikmc#cbu~TA4Ciq8hEe%y2hJ*(jdQ z<}u`w<-e`x^w*m%KeGl}M)sU>=Qu68YtzO^ILXR4B+VoUa^2x;vjmp`GgmNlY}}W7 zR?_3>6saxvxG0~ums*4&nv9t&OK9Nb|DCy80In!JE6(ch$>NjPh-63BiGNQSh0lE! z{CG(Af{q3-!NKek>q>q@1f6{tdbm)1fmU4A< zE*uytO;@#ai(2GK^vx-}|0{vUjiZ=aX zoudPeT(8S4Vj|KeCmgK8;8Z=i$>H$^$zN&80a$7Qh$Hua(T5G<#-&v+46NSqY!v8o z-InH=RN*os;@N#ALJM&C;nLa}4t8vo`rG4^a_jb1mUh`W?}4_M?fw2xSo1xSf~|R3 z(_Ddh=NFdI$z6eL16Sry%?=FfY zrGMUU{poP6QnM*9E0e`42u5-sKft8J;;gwQBl15UG2Qg0Fn&ZKVplPvC6pX6$HzH2 zR3Z6%bO#+udlJGyuPd%~{J%#vECcow_a7F}cYePx$AG?TcX# zM_}C0xeb93+epqwWODS%)yBzB?dS5(IlQV%|5F7%p*}dDz(} zs{rWc^iDf3!xUTMB5H}iU@Hy(v1$5JM6zhhdW@04SzQKr#mFw#=TA0rkKD$hS>GxY z;r2cC^7=ouUwr?R_tf-($lC^Q+xWw?o)qi3WRgQbc`f=_+F!Gc&W->cj=56_)q#3K zZ{sCQtgw`Rk!ip6nB85#@sgWdDP-DcbNLR$ zFAa%y1zM$d>xx{E%%cR?+_jpbtqy@Gfvyi}q)03#%t0~3oAYKlZwEx9)xjn0!Pdrv zL(8vu{-qyBGEKFP{cIKj5&Q#IOVKMK;g=7x8&=JLM#;pxtu)z$j9Uz!o$Or-G-IR; zsSib)llc$Ub2^ApRrvKy2ZWp z>YXxdowESd8Mi=(3-O{zLRo)t#i_`?Dx-+!{EO6{Gt&tTzJs|i#e;T*k3P{ejyJ7| z)R#)s7`wCG2hiXW$iKHT$=H9VHv8GW)s2{Lc;Jf_tyzk(8k!C@=Y$lE#mLh4qNNqW zXbOQ>IlP!p=x4Li{Kj9Z81&~jHAggqK3e7yPIfC*$>d`srnxG* z#>F*#vuv3-e@=wJ)6V!h$ga>sEq!xLx3?~dKu)f+Qk4{ir&iR=XqafVbCqFK( zQ+qEotSMAOik@&vw-!zT@#d_}Mh!7TT z26wB9N^jo-P-fRy+V1N{1>&O$t_B7FgKxk!0@C_M-Of?-qQl!w9WTq|+}^eC8QJW0 zEWzxoJW{;#(aeSS*X%b{Jp_9CGVk|4wgG%=K!+;-(qU_`qN`pqfBmzCT=(Rc6MG4T zQS#ARZy5QO9C3;=MwhR1>X_zw-p>(y0AMp!HGH%ELHWq-(N7sgm{Ny4zusDwox33p z+}B>eAGeMbiknmkbJ)<$3thG5K2;KmkpgTxi{B=joR4lR&SCOxi~Dv>J+#JMXjyXX zw6+{b}{Vum4HWkWMYV|(WotV5?|Krwp%{$}IYNH$7obU2a zw+qPCXN>X^pN?1l4HIYT8*BNXnd)EWF&wqvzuXAcUZ3`(vrc7ANgEs64b3mip_+Ke z>cjlqVbqLXfvw_)nCA9c7CGYv0K;Z@+ZQ+{={d8p!*vP1jbxQ?eC5HMtUd*&i&{<3 z4sS)MMhmON>-@;#uzz-%_cqUFl2gE7 zz37bu)jTtXE=Qh{?6BDDquH(Vn^qBd?=ID8{|BAEe<`nxJShyP)lDt(logtJl;h0e zA1rt&M(o*hHWnTRvt;HNgU3vnHq1oe;n9rrNBWLCOWdSbpDPnOQ%!Rl#6h2r*&#C9 z9 zfAEV3OXia%MOBnGry>YIXvw0K9$MO`dB3XchS(;w==2{mUeEq#P))i1rk{BC%vyDQ z`A{0zRqH`oVss3r6PNtA<;@Eipvt~$Rls)&8%p5lTg-xNG+CFOtY_dB!Fq33f{^Z`1;S7fSpL6lr&6#2!vMV zcAd;4`W6FCzIk$bJ zcfF66i8($Z&5AR)0_cNiH~PD}FI%~T;w2IC?%1wPH?f|b+^cn))?Mb`F+tyNJ>af- zyXlaVUd1Xx8)sHst|uV;xtQp0adc^VTvj6CkoatLOlOKtFNUL#(>_~swWmylfhFeN zRmZF`T`ygWTLaN&5Nn1s1_OI6^Ym^bj%DA8#J@O zW$hU$$b3)t9;AAi@=HIW^9Pp(Z^C`&(%GO?ny^UIPcuffc{GkiBQD!!PSnX1Kaszk z);n^7`Q_5{yQfCiT@QvOh3^g=mlrXyL?>RVvSvqI`;p5L=E?q|+8<0>=^%RjmHia# zT3nI1!=~BE$KHO{+kspqT(0qkC*3Y|h2KtDI$M9h&{Qf~YBzi3Y2zyWN27Ee`PJ33 zppG_ecKg7P`bnh8?byEP_IV%fCaySvCgCLK#<7XY(PlkX(-GZVp0`O{EHGNu zu$bF}s&Pzk0~6y6M%nM{X44Hc;1wJ3fMUVk!nPp%?34>xi*FidGU>b$lJ8aQnf6UG$tfi_c^p0H&z`FuhZg zk`<3S`N1+0+06ELuD|x6qSWL$TP$B%m=etsV}_Lw7+8qEDFosa-L$Jq|G}u_M0(SO zJ1+*MwDQM?H8_c^4_PwSaB^}pk1FU-7(L9$<)CY@yaRb9$c4J1 zW0p)uyE4kA-;x7;E`x$ZH6sxR+rPV6IkeOnKi!dGvfFy#{==K#e?PR(wl)wowA%XB z#x4-cQRfagCBsruZ)#~Ma&8u}!gt}El57>+4X>H0%50Z*D?H$bYo8D!Nhhk%pVgyn-0`iGbh$!bOw62fWpp7fOlnzR8)_R2mwuYhn^%F--yjuaL!P^#mQ=*L{K zT+5p)b*n2_-R3sJHn{UJi1)I`D4qzHEz<=Cw%VR`@1V-EEHwCJkIn*M+bGd`SA2AB z%|TJ0p22H=|Dc#)Rx_D;yTgec{1)=z;BfUdsX%6alk4iS%pti21!2bCDOYuDtZgqf zuV}h%$@hyfS}e7p^cpJs%Un+M$2+VKX_X}xnCpQC0*PNRxpJyeQ-4l3l(Z*CtJQ?9 z%GEg>2EJ28FS8`Pk~LlI%H?#|A*d&b=)HT{NqXi-u{Q6U+qU8W3R?x-z_j@}aZ^)5 zWkic8!Z1{}%9S=PpXGyD$%*KDMTnmUYr!K@?X~$C*pk>xcF*bn0Q>os1oZTCDim(B zU0RlR75gW)f}F?zA&=~T{4`BMhUKa&gL13~(A)0g^166HLqD5|AXyLRW&n&hODK7` zR&fqkFiJYiH0s)Ltt{gszt{WG?L}8G3hDh5Z_vk;`qTZ-`rk4O^y+Aj2`MR<9%OpO z{fMBGCwgkY1*fvj&7E3WVZRg-laE31K$kX7e`ot@MP9Z#T}Y>)=JTtCI$^<^lUF~6 zT{2y@+%{b>=GinB-&7HqZY!!QO1FBJ>^!2SH0`B(c#jnDP)#FK>F4S^;}Skx8`CIt zxP;|6^+=pcHOsnLvRbLD)^>sk`+lp;CFG6RJOdt*ea7gF0(9$Zm_65GB{i zB4!00U6$yl1rgcu@oe(e-+KPj!$8_ze&cru$Y=uLW@MaI1)F!@dbYg%xtiT*_Y zPHS&oFNWIC&dJr>{tZzc8@dqTo?-I%cu)IU`yUe#20B8T@)3H5uc{({WV$J7Dgj>M zu??P@Ms~`oO+ioVPBt2LZ8y(2>@cYrOO;;TLUVDqo@NP!S5~(0H-4~_`x)v%RtB?q zO0vpx;MM6{+k9_Fb^=P@71DiuI-81cf8+hAq`@_)C8m~AWUymOhT)dA#gn+4Zfj9$ zAq`<6_wkMs2hR^^z$g%N2`F9t>A5i1X|++7JMa#xQ~P{I5gID>I%;zHJw#1IioY;7 z#m+|AA^Vwj5pD{2O#VtPG^Pq1ixtKVS-*=h&C_Q0 z?9uPqqY^S?B6ofqCmk1Kz$s4Bqe#@h+I4?l|Bi1g6aCU*>1t%$_bpw|W-X~-r!KSW zRh5`2qadFVkBttGnS!jEimVLz(SsB#InBAbBj8H<@?y)W-j)wD>PxN#UXaWoDISiC zs>7sL+i&Np>4f^_^a_g^8#k>gS5yThC5I|J7H0&~;I!Xi8Owl{(t~uXY{8zp$?qT9 z>$qu#&2Da|t&Z-Pyc16+Z!IqY-62FC5W8dSjSRd;ydZuUnR-c9eZ}he! z!oY4h_m==OlL$f=z}z@uXu@ww8Y2Ejw7+<4kG$cn9jj@istTJ1FYH-Knjm0|-p!6! z#YR})1@zoL89jwYv*6`t66K%ZlE>bJ$1dFI<}`jPBCiT^fDV7(Ug!>TVLF8!3u)}b zsq~}2GQ9-+h`pjp8`_yS@51@FCen8Zi#0SQfx+dz?~&L4(o|2DI8Cqcwd+r5_#Bm^TW1p~ux|4% zx@v&vw4Q3Mv}8xTfagE_0Xr{9oep86=HUx*I}x)S_-aJt7TChvK# z0xT~>GbQ}qjh99rBo1yKquQK6)Dn7nn&3W3wuPb$;}0`Q-fRxh%X1Sty3)*))gq^R zg$`{hNeK?L95uT#Tn{q7%e_#L`1@+;()3rKGtaj!lIO!FvaJQ>sebwW+7T&VT-Tq? zGW5zB2qk@!otj1}ap!HZ6UxN_}pa;%7diO_Mi7)r*kA0tHeonb+_L$Vmc;)niZ4 z^6$8%$OofK52aPO=z*YB`aE-PyO82=i3%~GK~qk&@=lghJi*z*OMb&_sD2T~Agj_I zQXm2#>RD2xV7HvtF2MZUZ6JS~|MDr(3p?*g(R}P%BC)H6j5n2|3Tmjg0$l7OHf6<1 zv_QC^O4-U*A{ubm(|^o|4>$T$(~528jZDRDMW}E0LrJq;EeuM5I$;i4hfOO!I_>3K z3e3JF*0Nktt;BHaK^$PQ{O#$KkbhJK^+L2=+s2`e?-qjeQx`R_oC5&>pWh{}<51;A z>7w2Xk}=zT)4=GamOV_3#V)VgqWkHh{YR_@>z7m@yAjG*re5ObJGrADXwjclHcIU0 zH^_djLLiGgU|2&#J1ZHX5Bu=bNJs|hHg2H|^re6Oz+$|}tbTIOY$5m*cI3JD?g!mHKj^r#=|0w}13Nt|HH-l!;;2B&)?cacgSpIGBlHnHb zF}8KN9xeq3p_!adefX*lKWXrN>EAfmJa(8yq?`X;U|&Y4!>$ZfZ92hGq?iXU6c;Rf zaXNw83`Sc}Rw2t09oZQnOwLCQSccxR~0Su|YLqZE`=>Zo3?=zT%5uj-Y%z~qZF z;aeX&8*ac_RJGv|Ni2aDq^ZLzt-zurH&5F!%{;KbjvLAW=eo`o$F(>Gph(^$^A&oQ$*Cg3li$19r*6XJoKK9%xP<9wLNzD(Bw?`+!Jf(gE=Wvz98wabKD=_7|D*g zAhC(Xgh;fr;x{fxl+3{3rQ6k@5FmYru&D*jg#Q7)f$B|)}7BB%!yKK|gGIO{; z2Mxey$ftnV7MgGK={eibhSYSxe{@8L* z7}Sd}jcqQ&uwx@9myi5#8JlWd8COp6aNg2j@MLGJE%FFx)~2-ECe?`V0kUX)6M2(gTI#6-oseI|w&nV~qoV_m*nFcl)dj1W?!goq#D>_Tb+2gRSFDBDDZX5)V;- zur1AV&!nUw?uq!P7bMrdkBDZL5ZIHC4A(m?X7PCdA=g}olEx0MOrj=B=Qh!;(+Ic* zZ2shMTn2Tt6|b~Sx#U4-;0swiP;G^GoV5Z=tZBp7CcbjqKMPoRaZqHQ;pty+UT6u^ zzaY6&mJZ^rt3_imY%es>zo($o1HK;!0-P<#o%a^@>wLaV(iWnTIEQH$@a~sQ`?KRs z$Tjya_{J6&G>3BOH=fz|R_k&y6eRAh1014#Fjj*%iuK<-=bnz^LuH=8mcApHhRdK| z9fV3a2xZcVCVY4yJYkpse8~<9YGGQuMxZ~1cHmke8%XF+&{zB(HWEv@JX?j|IAcB8 zI^H_ngy?5#gte}t^6-o4&}-5bAoXwGfgAgRQH9#$m#JG9RrwMz&~p$U8st3AG`F_| zw|tAAK7x`Q0xjl&#?Cag^Uy|oLtsOOX+Xgt;!N5Mh!cBE4&Ms6Aj!3mmh{>9j`f39 zs^RE4@PFvH`tj?tzz0uTKhp74x1t%Dj(u^0*bM1@3<&MGhl92Qx!l#jwO)`gHNcC; z;aUW8C~q;ybGr7kBw=o<6*PRf83_Dqa|QeP6XAejfPlUr$!j?v96_>e1K?2HeS{?Z zz{a8+*d^2#I5jXq3CjLu914a;*wYmiX#piRh>bB>Y@^Y*2Bq@&8PJq&#AXqdh>-_% zy^!4n`d_RCt|-l4kN~pK@e>v-$_SPDOc;I2dH##xa0Oif=CnQ6IHBk&j zXp4?Rg4W&nH6pfXH? z#h}f69<&DQ#5a2exzr@B@lOyox);sn9!Q>Z#r{0p)LlfiVx&mFdBFjceZTMQo2@&3 z7^sN_s5_HpaOv=@$uAO+Y-eci@$8eTzl3-W+<9&-Yz6lHKpN5CURu_#?w7XF0Ccfj zX_kVc;T?x9CN-PXOyJYs;Oe8>*EN8>WgFz31G3R8Tq8tM!pEai49Xijhsh9x=(pyV zc@=J!4b_(+r+h)<2Kx?-FF?D{uWJFb^d9(bU>)>30SOj-u-^62Kw-z)4dB>x@VY3_ z-wTq$W+e~`0j&M2mjUqe{XSn@NkiaD+i9Ie^`T!t3mK78I(5_U2t{@KiGLeLT`2~YH@D7b3wAlH`C(Oi-xvKwDyDljD~?K3C!p~ zCeky$t^ITG9_084Va!OA4oZ~iXIvxPm(BEN+9PI8EHsa=W1-dU_}bW0Tm}<+svI7m zH&6f3vUI=qc86s~t5V%K&M?#rlQ&L*Yh#pm`^ZOn`t~V7?fKUJnPdYWAmbL{fxBlX zWn+^^TS6Q4(4bLB#p%Oh0&Con9c0ddu(-2-LE>0ueEq;zvcc08Q0}eG=z#M@K&Mv| z%pRk)(KowBeA#yF4nZ9PE#TU`c|l#^%H9S}59XC#`ZKwDuo%7ti2G6CG&)bTmI4~? zoiE~(-Y047CNJ#ONn(qP=9J%M6KL?i^RRo%jt$06l)#LCpuRwqd^qy_*bhJBsZ&xL zj47}<@jI?61aY+hOzi-iox-`<0+XYS8+;Ki(n)x-HWEyW6T~DUeVST#*%mZtvIqAd zi_*;mK0IT_LH8OI%~g6q62iNO1@Co&(6*D`2%82x-(fJogBd?F9vTyY3oj*%K~EQd)PrRtZnCv0c^Bqvy32vykCnJ-H@>gDsqe z1`WD$S*NDiH-K{^CpKe+K%=l^-cHQ~i9Nc5O`GtMM&3Oo==n@pP{#JI)K{M%vF1n# z)Ohw!oS9W3o)3B>bL<7pZfmF&ZdM&olm8w!fdLw9Z4?UdNh-GBfMfgsLwy!#rU*j0 zW8`SQd5ISip2Q#d46Xj-XlTu$A+4me25AA50sxAm*F5n-ObWtluHH8AqG2W#Qd3cUvg^@)axmMwQTRtT_i?h!N(cfqJjbW zYt&qjbV(L%jA#FKEsg8O_?cOQX7UKvDg*a--z@$Th3@}&%^y;PttP-u7Y`^`6zJqE z4k&lQuy&jx^v-y8J9ZX=!RwK35GWJ-i}-fW;i`TIWeE@n|5QLXRtPkYPv4-g?8h7BN(Sq)xS^Z=01>)Yh!;*r{RihjjA_=vRKRC>l^XcYDt~(kC~t(3%cNS?u`Q=;|S=HSfHN0GY;Fo}207A2@Dp zDC^`wF#{Pg-L?+<)k7uo*=AD<>7c@C9CD$xt924k!l@z5{fuRG)Wnh>mATR|e&A>37fnkNY;bI&8ZU%-F1_q$u94@Xr28PKD4DAdIX$%Y# z7#K>y%GSGCTyQsEtsnz55U6Z6KmTP%!wvdcQ~3BA85jzf7^aJgG%&HW0W~r*Ol4qb z6jyFiG^&%+sgcn#5msqnV6d}F42|xHP3{YcYK~59lTox+)%N!bZ7e8XnO8g`J!gWv zikqWHQE|n*!txoxk#)+NeyZAm&Ys1d{#CZlSvHPon))FMYM!&%+1A;b?1>Lvs-n0| zL+wCj+&Xjp6>e6C%X0RmMK3i}UgcytPeF2tjsBtBq&?nt``j${IGJp>HD0Eqv|LSb zd$ix~#IOT_E=OI>PTJ`m)|NbIsj*R8WtooV_N4G#fi8#LEza2KUQiP{FT;LBiv5_G z>QV`@<*JGs&D4(A=$_ROyCutUTbARz65nbQ{q;u5+m-l_$#7m);JKzMxH~FzySe5b zQ;p+pR;OJpwri;@mJ+Y1TNRbiS?!z;3`qu$k|4ie1_sU3Ev0AFBu;fOmi+v^myiFc zx8+6-YgzMu|NdEWRsa6o%+0-gCZE%{pMU@UtxUM_?cd)&dbxl8{fV}}@ax}sdA{uJ znr7v}ci-LE3pA54$=lt9p@UV{1IXbl@Q5sCVBi)8VMc~ob0mO*>pWc?LpZJ{Cjddx zw}iy63CZaU%zS?S`uXzl_Ih~+)7z(?w^uOGm=Vu#L|BB2lb5@{qo+%ZtG30B zp~;hiU5-jfNE{8me972o^QPjW&ngX@CjAUzZFN1Wy7ZFKCWm!%Y9cFLQ$x2lEt+KH zvAHYDH#fG{dGRc(BT2n#zPh=xv9@d)7cQ6^m>8KEwtkd6b4GWT?%D*K?Ac<`*46A9 z=P#bTdGzX8*%M3*6}Oajzd2&81a!G+iEBiObAE1aYF-J0MzW@Yk%57Uf>&a8X_7*4 zNor6swX?12r&sy85}Sb4q9e0O1lc AyZ`_I literal 0 HcmV?d00001 diff --git a/dependency-check-gradle/images/contact-new.png b/dependency-check-gradle/images/contact-new.png new file mode 100644 index 0000000000000000000000000000000000000000..ebc4316d844dea7c644b636a768348a4a105fefe GIT binary patch literal 736 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh3?wzC-F?i!z~~#`6XFWw{(0&D=T+#RHwAw` z&Hnpo&YySH^B2wT=xUuXq4DDJ;vXMY{rmmm?~n68U)N8b+W+is-}IT2Cr_OKQ8Rn) zjLlm%?%28R-u1=5z8w7b_w%10wGpKB`?6U6pFe*dJ9ccrf(7f>ue)&m)R!-BCQRynbY{!R9*ZYy+@7p-UY@S-`Sa%w zA3nT)|NhsnUlS(vzIpp-Vt+(alI*llmi}Ot{8X*wt1GWuxpMjPD8G_FtAwYlM(@+7PjBA5dHwqJt5>i7{Q0y0(1MB6!uuu%PnZ(1WB07bk00N^ zfB)XSdp~~s0NV5M7AY?6_YmX)lQk*=z#qM@b= z;jzxa-qG&i{`U`D;5cDwW@u`>eZ!Vb+cs`xE_y2~Gk1<|Ow8SwyS5T3HhcHf*8Kf* zmx-x4rs2+m2^The=s2 + + +image/svg+xml \ No newline at end of file diff --git a/dependency-check-gradle/images/document-properties.png b/dependency-check-gradle/images/document-properties.png new file mode 100644 index 0000000000000000000000000000000000000000..34c2409a7c28092f7437730eb92e25834a433349 GIT binary patch literal 577 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh3?wzC-F*zCt_JvoxB}^!GiOeiFrg6!rcRyO z-QC^Q)dge#$vJc8{Qv*|_wV0-{`~pzc1x z@?`Pi#gUPb%a$!mPfyRv%4%q+zjyD}h7B7sGBPqVGdnvwA3b_>`}XY_GiFp&ROIC3 zBqk>2=H`C-^y%l%pKss3eemGH!-o&gojcdo*4Ee8cjwNX^XJbmU%q_Jnl)d(e3_rK zQ5)znu96_XUAfnlM+?I*J`vNB)4cy(~cFE%!y3*C+dtm|AkbLP(0rAtI-WalPl zXQ#h^a3Yue>8TkOmX^DBoNC%>bIn0P>y;XJk*Kt_xlBQUk->(IhZxnF8MX%rzU~pe z)edx+YKdz^NlIc#s#S7PDv)9@GB7mM1tJ5>5Ccmq69X$#3vB~KD+7aX0T&LVXvob^ Z$xN%nt)ZPaqaLV%!PC{xWt~$(69B9}1)l%_ literal 0 HcmV?d00001 diff --git a/dependency-check-gradle/images/drive-harddisk.png b/dependency-check-gradle/images/drive-harddisk.png new file mode 100644 index 0000000000000000000000000000000000000000..d7ce475f83900cfe56bc5374932b5bf2ca4dbc8d GIT binary patch literal 700 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh3?wzC-F*zC&II^`xaJjPLr`yjcXv-mMOEp) zfB$~|{Q2qgr}E0uH*ep*0fM(c8pHz9pFVy1{{8!_SFc~e@M|D=_4?z-kMG~VfBN+4 z=g*&?JbCir!-ub5zrK9=^4G6l&z?Q|^5x6(=g-S4OG?X&9zTA3@7}!^FJ6?E7oReKBW~hUcb538A@(YtL-+^H_dcdDlJpJ=Y$-@O`Fz zG@0+R=gebQ3|6LQE_?ex(qMMck(v6_v=g$+AOFmI(3&Wse&EvEy!Sf~KCI~aV|0G{ zk1FrS2B$YEFiv@18F*(Wd((ez|EgADxttge3!oF5szM@4obz*YQ}ap~7&xwf_C2e8 zRrlN)FW64!{5l*E!$tK_0oAjM#0U}&fdLejY7 zI~FXQH)-jvha*6u#Df8X9ChYuY)a%k^~E2mDLxODNt zmCKi|T)zC|@uR1YAH8|~^39u9@7}$6_wMcc_wPP@0HXIFK79E6`SZ7LU%!9<{_EGT z|C9m6e^Smxsfi`2DGKG8B^e6tp1uJJ`FRS73ciWS42nNl7`Yhi8FUzc0OVr^w%h~r z3p{khINcN{dHm3sxp?^`71bH@yqi{KNeBh-JDpc0PP#ir~m)} literal 0 HcmV?d00001 diff --git a/dependency-check-gradle/images/icon_error_sml.gif b/dependency-check-gradle/images/icon_error_sml.gif new file mode 100644 index 0000000000000000000000000000000000000000..12e9a01a930c8dfa20992254a9c2b19272d1d491 GIT binary patch literal 633 zcmZ?wbhEHb6krfwIF`;38Xg=L5fUB=M4=H;VNo&RafvaB$?-`k33&xMO~v8m6{R(` zl?_dGEv=0$ZA~rhO>G^`?Hw)coj}yu(b?MG)!Nb3($Ur0+1)m2a{u;z-^o)aPMJDs z`t(UNXHAo#m!w{g?@=WBc~Zm8X~W#g8u zo3?D*v~~ODZQHl}UT^n%gZ1x?R=+k`T;JBTW7oDFySD${^*eoz@Oc*hmRckzCZ2A(L+a%9{G7V>Fe>N z^XJe0KGXR7Y}4;^^*`^=|M7h0?^~=l4^&mpY`6;P-`9HR5qr6O1d8TwsR`3>b@UzlT;FtFnna2=nZ#cumG*CCfUXh`R z+r!d5z(O-R)XZE>lB1r*D>%&0R$Il*Mn_6Qf{%sS(JIbXUpX=*NJ;FP;1pg}V|6*} zv?MJFQE_3;iOj5Q?9#Ex;l6qz5+~F=Ii~BU9y&2WMUzuPiAOcCQYbJ`P)$^n_v8t~ IKm`VC0O`0&yZ`_I literal 0 HcmV?d00001 diff --git a/dependency-check-gradle/images/icon_help_sml.gif b/dependency-check-gradle/images/icon_help_sml.gif new file mode 100644 index 0000000000000000000000000000000000000000..aaf20e6eea4148fe8fbb09bdf4595eb98334fff6 GIT binary patch literal 1072 zcmZ?wbhEHb6krfwcs`v$!K+=-yF&?xd^(hUI+cApRs6bC{eh@k&A(ecpj#`rPbZ{T zHx!8a^g{b}!zSp5_v=SYG>n*N6g|Zlh+?Lg#7s4dnQRg})go?+MZ$E8gc;Te)2xza zS|`u4Ntxx4KG!L8zI)~z=dAgzISbu#7kcN-_sn1Ho4>%jXsJ)pQs3fbfo02sDpp2R zERC#K7E-k)vT8+i)$*{KwK3JpV{2AK)o)0wTb10nI<9$BO4FK@rnRX}Ym!%=V3`o!hfJHsy3|$nM;n-n}!oduvYb_N=~Lg}qy|`*#=hZ!es< zJAcyNg30?!r|d17cCdKb!IJ3*D`y_8n0>Tq?!mT&hdUP@>REWOXVJm#rN<{MJ>0+I z#FUlCrmQ_Pd;RIzn=UTca(=iaqXVV+mGGa zb@J}slehPtx^v*n-9zW@9lP}K#FZzfu01_{?di$u&(B2A zoI?4BMCM#(ZeZdNx5?S*;=#(TTgt)U(ejX?g-3ph&!#D=Y`v;IOgUFKENEgEY}K2& zbK&FTQ{0&t&PXaHI(LYby<^~<)WRug%f?Vsn9S(HDV}gdq)=(8*E}P}f0hC+DlA;` z)Ad{zHa+cG#KBxFQ?<#-BSSmll8aH3zyUtzf;|p9o6`Ijt8uE?Ni?%hQnAZc^O50L PaG-&a!$_HjgTWdA|E#c| literal 0 HcmV?d00001 diff --git a/dependency-check-gradle/images/icon_info_sml.gif b/dependency-check-gradle/images/icon_info_sml.gif new file mode 100644 index 0000000000000000000000000000000000000000..b776326703c341ce559f98f028bb92fe4c332a83 GIT binary patch literal 638 zcmZ?wbhEHb6krfwI99}9U|?WrY3AnUX5m?3;Z0M>*4P;bV`&8Ka zl-c-J*!q^)`BgduR5=D#I|r7#hSa%**1Lx{c!gJaL^OLwwt7Xic}F+L#o2`7dnmC(1Rt2?c3!lt^38_VY&t(beHXZDWXIXh-7+1tM2%&evRR;+4S zwr0k}b!V5aoiTgei6v_fuiiLg?#^pV_uW{w@5aglH&-3Jx&6@9oky;1J$7sB@!MNZ zJveyg`hg3N4_$b0@Y0i`mmVIv{N(WECzr2oIC}Nz@oP^{UVDDw>Vp&4U!1=A;>^t# zmu@{ecl+ht`>QY9eSP`<>nji5TzT;J+QYXu9=*N!_}$}YyB<7!`{3D|d(S`KfBxyw z^Y`~(e0uQm)1z0PU%x&0;{BHw@4vo%|K;_EudhFRd-L)8=Wi$9eg5(O^Y^bmPJRCV z>&y3FUw{1i{`2>*-+zDo`TOV3-~U7d#ecdQ$(jmA1_mYyUWwVINeaOwshN4HMO<9Y zMX8A;sVNHOnI#ztAsML(?w-B@42nNl7`Yhg8FUzc02GM~?5i5;o0>S;m|56)n!B60 zjgkxVVs!X>ns_~P6XU}IL#+gR_>6Khb5di2o!vBrx&@MxvJ29p102vbQyButm$y)r=@GSbQ7fuf zG&hu(RxhgI;Nx!Xk#a$OMKhbYL0W}^MFz8kslSGfx4@b6vWfA)m`-W&brNWq_@1%Hm^{yEe1`?BYsvn_wmHvhTm`R8WJ@7psnMoCG5mA-y?dAS}$C^BFZzMd3&ORu3u6b1u&a%gnW4I(EOT#*fRVX@ zj=Hjv*wR)(6J1pWB^l0kHf~;N6*);RcGfnA&uq+0JK1LSU+Ld<{2%8ZVGags09itc As{jB1 literal 0 HcmV?d00001 diff --git a/dependency-check-gradle/images/icon_warning_sml.gif b/dependency-check-gradle/images/icon_warning_sml.gif new file mode 100644 index 0000000000000000000000000000000000000000..ac6ad6ada39ea693ac0500810196fe551833b2d0 GIT binary patch literal 625 zcmZ?wbhEHb6krfwI99~a)zjYH+tJh8+1uaM2SgLPCr;{|FsXOac1bJ1)uHC+K>&~59ckkZ5d-v|2$A0(j-F^3{>(7(0`}gnuc^UfX z@x#ZDA3c8Z_|NN&Cy&7yo%%@b}sNzt0Z-eYxt-yV^f*C;fTf`1eES z-w!>1J}>_JdEuYWOa6Xd^!Lk}zhBn<{kq}rw|)P9oc;IX{NEo}|Ngl7@B5>FKhOXB zdEwvh=l_1c{P*YWzd!H({eA!M@Av;i1I2$*&PAz-C8;S2<(VZJ3hti10Sftf3W*B7 ziOCF#KUo;L80r~x7=Qp2V+`yY8tR*xTUy(i#HHHXrMkN7MWySl%=MJ(rA6DMjY2bX z(u0-cWZJ_D^HP)IBjwwzGV=?v5~Cw*Wm|eJbJMa@;-dULC8WeVqzp2WlM-S=yxk;w zTU5hiJ%ZG^dBjB8Rrm$j6kTluIQSS_WQ2shECQX()EphTT0}XuoqXM`9onu0Tx4Ka w$mp{`;N!m2?G#bv7+&QNR_PU4c>CU?Yd7!v zCbwpHY-*pkZq44U&2v_!G_8%VTOC`oD!O{**^Adgv%311ZM*yQ#LwTaFW%i*IeA-A z@3#EzEqPsA+@fn^3;O17+V%L=xj%nD+<3I3bN>F8+54Mj?rog0*FUK-rF7ElwI|l@ z-F@uR*5x}6OkZ_k;*x`HQ`b#ib}T%j_1dlbSyhvlZ@aL3`-NrO&M)11e$xES3CS6g z=5LM8ZoPK%UO;?h*R)lgQ&+Z4T3%Gs7Z?~A8JFhdpLY4$9ZRn?yMO{)|2!MNJWKCv zW7lL`*AQR-Ky%j^YoCme)TZE+#=yjSzxZ1J`0AMC0tfGyhfkh+gctq#_3O!&WnRD# zWGV^r3!b}?Pij{wkjGiz5m^ij=<6WN=%g{b0w_4w)5S4_<9c#Jf)f)DkIxyMH30_> z9Xog6$ib6G&mKN~Twg&$h383EM^~q}hnMH+6I`bncYNaN@;arpD(jV0!n$SCw)L%> zx36)b;Ee2?q^z{O#LU!O=0~?~-L$@8ZDqN8$F9a5@8ssqn-_P_ZeQI$g*=CZfC7(< zh#mPZDl?=-Wrd~1=TDe0f#Z=Hr>ZmK4auBCMF9$P4xKx2qK`#_L7_#4?d?zg6F`Tm zmbgZgq$HN4S|t~y0x1R~14BbyATqEFF|f2UF|abV&^9o%GBEfSaN#hDhTQy=%(P0} V8rpd?>VX;$?@>Ltyyb~Vk~9a*^;C>T~aH>F|OjI}4Cz})28B`tGy zx6IuGl*;d11Jn*=WVfx!?pOz86!dNck||9qbGtUAHm*!;SeaC_v~I>upkQF;l(?Fu zK!$(XgoK(!O|y4LRxAW^T_fva%Vs6kEY1WOvNpbYaYWht@cgM!W%GeHMwHAAFP*>p z#LaWp9^8HM?%eHHyH4Jkx%T+Y`_Il_yL^=YR=(+3np1ywY?Cq61k8eKv z{P6w18!vtwJbmrr)f=zheYp4Z?XHuzA3lC^?(Un1AO7Ed{pZ-(D+f!KoxFJS-@ku<{`|Rq>+b$jH;!I*p_DfBg7y z@BaOLr*3RHa^uD8cVEAKJ8|XFj2*Z8H{WbrdTQ?GGp}B~I(XvT{7olrJb3y0_wNrM zKlZFTQ@QYL-pu3m3y)p9c5TanGYzx%Oj>p9%H3yM4xY=JawxIyKt%iQ?8*CgA2~l| z&58Qidnc|tH)G4?zBOm7X76v9wL8Cim#x0cV)K4{ zUn<42_|HnN;NRb)&+cUZ^^W(i;NN$*j}`pQWIMj!;OxKSilSZ5|NVJbz#}Nc&+ZsE zWd_h7&H|6fVg?3oVGw3ym^DWND0tS>#W95AdU8TSLQ+~{YVz|3Pm&lI^W@^9t*hDH z?dlj6`~yy$ym|EM*}I2>BV495I{Mr>ef#+J^Y#h`9!`@Q9knb}OmuW?l#H~j+@jhX z&CK-d6cr6MEmci@{pKm!DjRECtDEcV?_Ut$IMH$CiXBU~tl6_@)2dx=k@FmvZdKOG`!VuDc=fnx$+R6#>c^>b&wcOS?|$!`a}U6ptjU_J zlBA}l*3{J0)YMd0R~Hr*dU$xO^ie1jhYlTLS+=C4#MRYRCX#twGUSD6Il$6AA+=UAlkY(ZF;m4037Yc>v&!1mPsNXdliHV74&z>zUEv=}iC@U)i zfc^XTJ3BiAKvYyzczAd~K){|od(ip)`}f`5-HnZnv$L~Hzqq=(y7Kb!>gsAwPfu@e z@3gcu0LabFC4?{xBNPh18Fpy3+Tr2hfq{Yc_V$w}PjVdhGtMTH$zU){PfznaPmK)? z4KH52=;-KZX=#a#jlFZ{PF7YH!!Q{c8Taqs=Xt)UsK{tE{@>vc{2Hgh!NL0adH}e0 z@19Df^78Tm0ES@zz{SO7Zf@=upJ1_AP_bIAgpih&mWqmsojZ4GG#a&9{f)&Au~_Wm z<0F^L4;(mPHk)-io!M*-3JMa7#VIK%EBy%}_$g6IPEM9cBvPp~K0f}{t5+6_rMbEJ z(xpqcZ{G$0j^p<2+vnuu^bN3MdU`rLJ3Br;9ss7MrVbuFxUjHLQBhGX6WriQ5|M*_w z@5bUDdV71dTCG;AO-@dx@4a~OA{y)K>k+2N$jAo|9?w z?b_+nr`2k;!{M;o?Qh<^`R=>#RtFA0KR<`Vfh)Li;|5+X!otGn&U<@%H*VaBDU;Gf zr_<5=()7Iqfmk>yLj`}084`48Zf?d|M~)mpOHfeI{QNv2WMN?;Dk=&9GBY#LVzb%$ z`};Aq6GAK&OK4~)&U*g*IT{xh7M8K~%9SgtQ-;OG#ZeC5ym=F=X|vf(9h#b&K7RZN z05+S=X0xGjU|@g-%ePwl!GC`7t=5VDruDp`t9rXwq=tAb*88KQqo~N`a#V_oixKzA z%F4dJzL1cRy1F{CSUfW`qfjWeZ{Hpm7>H$yNF>V6&c<>vGBOgU_w@7}J9g~o(WA6z z#sgc0B0VlH4i&T6{Pyiz)FUDys6$s*7rnXCi!3z)!0DGJ5eITHyM2Q|E@qtti{QRD z*nbiZg+h^&lY>QINl6I+oH}*N-Q67kYHMqqoSd*@fE67^695Pa36aTU0HD+95)%{g zFw)c0Gcqy&K&4WxG906$qk6p_b=txpgmiazqaGF(M)NU+!{3cPsc^{*a`Ja$nXfZ@ zhsL%N4whw0OG`2M6&4oG&CQ8KBHBPHC@3f>C|I^a>__(qFp!^RU zV`F0uhl6EVxm><`_ijATmoHz|)ztxjL?XdmSuB<(Po5A$mM!w}C3kdS~ef}W>dub-Hhz&fI`vJ#oXvTST@?6qsxN=r)tz|+%n^XARiL+I)0 z!HGL|?4Z?OC@z>ppO+fmk zEDIk1FgrV2R8&O&@;qNwR)+h@$;nZx)dqvXVzG2}b>-#d_4oHa!G&Dp59OYMg zd;9A2I}{29&+|ObzkB!Y^XJcKjE;^*({SomlT)I^E^_90Q{xPG;bvU;38ml zcng&pTZhKxAmAX-{xuvUBO`bZu-omWrKK8;X6fkl>(@`5I6;GyySuwkDCBv*tE;QE zwH1kg)0Ijk1~{Qms8A@Vadob6a=9D}VUx-9>C-1l1S|^dcDq`w#&Z*k#hB*+K%>#n z=0$)zo8T)X1Ujc}V+Omw8!O@%0GKp7%(fp1ER{;7QYogYiHQlT)w*&q5{X2iP;Ak literal 0 HcmV?d00001 diff --git a/dependency-check-gradle/images/logos/build-by-maven-white.png b/dependency-check-gradle/images/logos/build-by-maven-white.png new file mode 100644 index 0000000000000000000000000000000000000000..7d44c9c2e5742bdf8649ad282f83208f1da9b982 GIT binary patch literal 2260 zcmV;_2rKuAP)4hTLUyOQ{PVbVY5&Y3g!&hN~bnR7}ZgkXUt ziC%zU0gf+&kEv>t|d$x|zXw1mS0D%1b{8z7DF%0wW-8(XBFc`A3vVI|O z^!N97baWg(eE86zLn4uA_wL=Zb@+UKU|=8sJb3V6XlSUctSl!dhm4xd=KJ^W|8h2q zR4NS%3yX+|NKQ`f?d=7Cf`Wo)&z=E5TU%REQIXYZefjbwRvsQ6zIyfQojZ3l8V#{v zv)R(q)39Vr2GBPsa+apV2%%fIZY3ln0Kl+1Y8c*(xe3X6sWFH9kH*UDDLl)ZN`}u~;f9D%P!A2LK5P2`MQl z(b3TuDUC++_U+qm01k;n!Z1u+TwGjS+}X2d^Yil+3Pn;B-~q z{Qdm_z{kf&EEb1^gw)j3R904!x}#RBj~+c578Vv16olc}xpQZGd;7k9`>@WHD_2M| z{%VB2fNVCK&1U^_rTW_bx`C@MK&%ZR^ybZ*=;&yb zN);0mV>X+~OA`|lRVtNAr7A8i#zL)DyJycHxm+$5izO0?QmM?$%p@6le0*H3R;yI1 z=;-LCrlu1oPI!8HIypHhmCA~Wig|;>WHON!GbSbmcN`jxhJ=GssnlpRR;zVzaF8J4 z>+3sJhW@0w{LH6-`(Afr<9kMWBXoSUM7Dox&JGJtojOI96z3EG z*uH)HWN?qO7x!`hzQnzLg5JL3Ui^ps%X$n4`+YK2S-yNZo>gC8kJmXUC#D?-i_a7IlwdR(Kkw#T>s)<( zJ!ZVTycREBO!{t;H9|r{F#q)FQ_`LjAsBnPnnKk2PZ;V3*7{M#@%jyBNObh|^_fg2 zd|f0I3eTTEPf=83VhUbHWgRft|{%MRRMp6H>seM7wV6&k5Vn7H0DDSDT_wn(;aaUDU zWi%QoiptK;CgqIWB$bwy78Mm?w@oI~&6_tPBO~$kExCLno}10)mX;RGM?^%-PjqOt zTFi(#=@4C7NJmxEVK7l6G0yhEp_Lq9)1fj}S-2%Mdrv$L~tStVt%xVSheDG9e5EX$6J zj8GIMm&=bIKaK;TqoYG05D0}r0!Kqb1E0?q2n1`_uAR{_f0E{OgnR$~y~Sd|+0n_# z2@6L?MsUQ^H0|QzLJoDKqobtlneyk|8`Sp{cp}PUC5RRQ^8?;2;Iss$eWk%*n3$Nr z(73v~e)3}s219#$yTM=(2n6o#?!LahxUO>?H!v`O%bZ*;$Ideh!!Qg0h{fVXix$lf i91DLtEx@rr0RIK2cl{g~?Z1Nn0000}s literal 0 HcmV?d00001 diff --git a/dependency-check-gradle/images/logos/maven-feather.png b/dependency-check-gradle/images/logos/maven-feather.png new file mode 100644 index 0000000000000000000000000000000000000000..b5ada836e9eb4af4db810f648b013933e72c8fbe GIT binary patch literal 3330 zcmX9>c{JN;_x~o5Ac>t)`_^PEV{L6MNl>(?QcG&7ly=N-Xep}HlEki6%d`xGQff?J zZ3V5?nxMK^TW!%rlc2Oi#TE&YeBaFbd(OGfJqdI` zc>}=J0{}qD0)QP*?7suRWeWiKhXeo)6#$?b`+NA18vvk_kGT^3lRrj~)ZiX~E=7&X z2SKm_0zsnO+$cbVdd$U-?NJjv4pVQ1Nhjly1q-WLl67`_;z%v-QHPc;g_!S~IRE^{ z!-r;4Azogl1_mw!0>pbvoPqVZ9U2s5dwy6sHa1p4L7^@xJ3CvqEtc6=V;Sjo`SKw` zH=oaUc5x93g$)f2RLqLwrQCI9Ez?$q{#(_7txem8O7-r(E=u3NrnVzb>g3;N!E`D4 z$F(MEarBhUUxI^!j~_>3u~Bhx7JsSR*w|dSa6vbc*_R&srRM|ftV?XHdFb}1C$WrQ zvCqw{t=r+KeZT{28=Et|SGiR|Ew_)PCPc7HL$FRx^tIjT!gS^&HZAG+)pJ^j_L!yB z-&JbQI5tJZ0TS}9l}GV-#=yY9@UZdW!+Wo8V)3OP+M~kh8Cox&UgiEXkb|OHrtnt7 z^5^7qoPgd(mzSp^UljFw^Ea1#($jleS~zn<*Qt%~?;g8p7T$+e1_e6_0RivD9i_fn zntBj|S0D{TF>ZC0BjrC=O}^<#pa0LS&uvarfWzp2`pUd__f_%7YV~7dt=r6SgMYpk zjT&tozdBVDfMU+}3PBKu{I@a0eE%y;<26%LfpraXnsz78oRL+ASlucsJ9Ov}^-cnR z?X0S*D(PH#SsA1;IVGjHr-u@pc=<9LQ|*-QU~8*d0k5yGUszbEsHmW5uYUjj;c@h| zc=i>Ql~f4Q{2jFogTeH_k#4q)N#10=x?L3lT5fn+n;f?)a5}#)D(b9?5F`jW*8R2B zY10|kzu50Yt-pEkr?pP=J)v#j+39IETXnv??EKOqdr`^I$PR$!&#+i*wr^07q=V|W zRr`cRLkwol7wvCgY>XVWV#HBVP$e>vs8#}bhe8j(d*@G*O1g5TCFF^jnVIZQvS`z% z5v0FEpQe3XqLbN{Z+4@!!}?n1jYn$VqUAWElr$a=d)NRcr?dxiBP0c$a4eq)C6kW} zg`-#3YZthl;XEcu_;g!xn!}4v15@n5*WxOpB14=8A8Dk>`K z>FLRD7bsziv>lNxci1YB3`T!HV#jF&kvayv7^9-Sg&l|eQ^qB(FU%g~JDx-!K6@(Waovi+Tc$s`@s@Sv* z9p0C*!~5#c{h1>d>@N5DL);Ea=d|PU4}@o zGdG0Ng%R<9V_jn-yfB3nD7kxXb8!sMIXlJ1WeD*5?60hT&XSa)+yVTVl9iP_o8v^w8_0650v?-3$V0uILqsvdAu+2y6|YCewgNhga^h4Y-lNq0Cah}ivo zpoq6EpmWSceZAoF%B5UfVPU3op{AfPhFM{FSFJMU!)c~SDTMch@trf6$~-E;5xn-d z<8`e~UPj0w%vDYVje(iQii)`c=wzHbR6^djAF^dnW5A}!CD-JMWyVHEkW;BwukLPq z9nsR%B=!TuB0vQ|DPO#J@zkle(n^?>&z)~)XSMt|Ks2+uT9af6QEqK-hanLX5&&xP z-l-<%m`WTuBR<~hh#iYkQxoQNXtTFvX)i0JF_1Iu5Wn+7^XJlfPFX+T%IM9_7+4B=%5Y=a!X6S`QV)~knSitusE`|vEgD?+D*SdgtN-v z@2!tnPsQ$W9OoldXg5!7EGfyuKEmbk%8!pz518D&%P>a8*ji>n+N5Y15QI!N3aw76 zk?~TlC_r^z21V(@jrIB2O=fW{*e;OxLwTOl%b7{65NYoUzv46uU?y1WK`h1$gXk#s zGM!NC1T6)2&vea(*Gjoe-Y0OseT68UKVi7GtWs>+{mTm3?9wmCl9JqVL7fcIg7PHy zS|uV8fd^!W2I;)j*_@ml#-BrjgIWH)bTI&Jf1fXAax!YjYcdmoW44Np%MhjRZR?D*fO!{1UqRj~p#EAohT=T-17$$k6AmQb( zr9h0V!aUsY=NL_BPmf|~=n=+2*+gqRK=3w1+z;yxltfUx%}G^AqM7qBoD>Zu#))>h z(O-H}7=Go_Xv&X~RNksk#{u}JDqbNyJIauD&lJ!>cpV`%&T(-`&1Vx}= z8{BIG$r-+Li5}_#{j}s%FlGk$jM1|WKp=Pv|*T=m!~I+rUjJ3F@7W!gumQD8RFwVZryr0 zG6IWssk0)%eJuVTRDtKPo&xDaOWF|RzCnozye=JYW-)oDFHKrbK}AL7sWkcH57B~D zWIZ`=QNK#g)SEJB!`69JGO3P=r08pDX))Bb6t@_;R!2TlYhv>Ek*cIBeDucB zNbDTV5C(L01Ze7}3Kc7OC~(zLdAV~G`9N+1xB3ie(wD=k6U z@g3gU065J9XPq{lyp>keB&(ixxdnV8$%i$asL6b0O)JUdYtCpuubGB*DbEFHXlQtp zXgMTG%@{+j0dI{Adnj6-$)BcQylA>}r~l(e_1pE-*`Eac5PAGF#EWMIO6;2ECZAeo ziPF85kd7Ft6f{I>ZQIUbf5YND4#d%gJpKl~IaM@Xl!bUvZj*0lQRvUOOhugnVG zMF7OiLdS5a+otCLNQI8V^8vu3ka8NP_S>32`v3S)2n{Pe(fRVLdLST=H+AiBqCTY3 zZWI=>Zsgp=`Z%jG=8)QMYZO=@1A#!)z2kiwpnq3DhkpUGZV&>CeaB0vA>Y6+Mrd+| zrA52d@P7Qe=6m=0Lz-`5yrGM(x*9Y0sP7_5T2*v`@~JgS7L3#>yY-7x_MJ+9`9JqyEa*$Q0 ziiL%hken<6A7+&3D;!0f@qP3TvIRVoufv)c8?&aw&B~1Y(02aUpDjK7B)cSkx8QDV zQMj_M+x+$UXOfa)nmweB@KP^Xm2R7$9(p;LCnufvW}*eG4R>Eak)Ei}%-KE8gsec^ zj=HuX z(qyBjd`DTC3ZeF2!np?{CKA-DtE=Op^zuqOJMFU}UTntQB1KKp81%{!bT~6heKA2v zt?`kF-Zi+k^YcNCz>V!+^RbV}r|Gp2j0+=crL`N5t}4tX=Ugo&7+C6ua?F4oX!wQ+)83@^vkY zDLFc>n(A(&_r09T&@t7l6XQ+b#6#=gA#14-D;h1Uq<(+=C8$D8`D^qmZ z9NOcdL`OIEho{GDl585|eQ0-*j0e6Rr=PNtyozBAqJr literal 0 HcmV?d00001 diff --git a/dependency-check-gradle/images/network-server.png b/dependency-check-gradle/images/network-server.png new file mode 100644 index 0000000000000000000000000000000000000000..1d12e1938ac4d8817701a555a97b36a42413ff7f GIT binary patch literal 536 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh0wlLOK8*rWOiAAEE({6J?VYlKJkA1-$YKTt zZXpn6ymYtj4+8_EfTxRNh{R>v^Lzb75+zt4q?_IE(UC6ToMFIeXrjjU_Pbcl8wEu* zmFNogJ4~&tCL!OBSWj@$7M9kE%GC+rI&-8+^}#zUfge$ z%95%FVq)d@YWpHh0*~9IeYCDS=DEjWT6&NB;?38!S{%Af^K0ULzq^XpMf{AfPW9%` z{By-F@#G`{r|bn{ZSl6`PhU_~!26>8WB9W7wxA3jxWq>uP}{$dFi` z{%E$YFs9ZZ#)XBd3yahj7HcdhP@0i0c5-Fei4|q1R+pb%U2$f0$(hxq%c@PLC-F^7 z;+vfzx~NcTNs0RMD#LrH*W5ZZ>(GMCN2iutSY3E&UD>s*_1Cu4-#;|z!_Cdtc6J?G zUUG6}>4z(;KU`e+;r#6P=Vrb?Gxgo+Deq2AczdGv?eU&>7nf}8_Wf{u{fF!8K3rS- z;o6$_*H*v3y88XKb$9o403A6wmUUi^)Rkq4C;QDWElr%4Ewvz5_U@*FYx8|>Z^)aU zBeO7H?&+SoN9z+G?W$goC%33j@%7nxua0&%tapcEij439aV6bJZW8_q7iNx>mKsHKHUXu_VbP0l+XkKAq+)H literal 0 HcmV?d00001 diff --git a/dependency-check-gradle/images/profiles/pre-release.png b/dependency-check-gradle/images/profiles/pre-release.png new file mode 100644 index 0000000000000000000000000000000000000000..d448e850cd3f885844d0c28da7dddf4457e25300 GIT binary patch literal 32607 zcmd42g;!MX7dML1VbBfI10&KPUD6$bfOLw4nUu&L0AceO;Bj>K0bdyEkF_X*pdXyK?5$ zCZ>-+!8DKJypGYay4usSc2ShXYLwn)dsrQ1)t4{qIVp1 z%U_i9{q~3m-5aqsIdKcQpF1kMk`qP9+H@pb0~@ z)v}lb`-Uld-mD_(=WmE&ZvItV9H=cd%M*s?#aIzXXnbZ?X8$2p7n~9LrhC5QNHO4@ zulD-2d+?m(T<7e?{^)+yo+-*&VSm$8S9K%>L$oCYq^D*1RkYTRL;{R)`CcY3;*%D} zd+8q#o*h9`zGrDs|1yQ+xHZy?hKX%vGx?VJQ{)NCERri2dwgK&jZY11%Pm}qcXQr0 z{Hyq)w~YK3I|WB9Bi!VEc% zk-^ag&hD%sKtweo083T`hxlnLh0ui(wCBb-;7@11iuJ>fg23`#z}biBbXWZfy1cy z{~h_?%l|v_znA}i_=f*Ko-xW#%oQI)`nA`1PW_2W0UAr=8w{oA7^|l2GQ#^>mCrW< zbV2I>-S!^Ix8YOKgf+Z8H6SZ1a#qXoocvQtqNiE$<{*#jn^L zz>ld2oN4Fix*EE;Rd~e9iY2VT8y;0|%3j(X#L`5-didJJXeM$_F&;~;)EgK*O{RQx znB10>a7c}->m>6rV|y!Km0&4+`cYDR;VPzNez6~u;XH`tN&hJ34=XmDo|9414^otW zW_j{x8+oT80-lBR)+9Q*NA$XanaWCA6so4bhg;$HCK0Qg)^)qYcCE3ii>A4&1H0T} z1tjj$|9gVqZ+V#+THh%A)8pGwau%n8Br9B!X{Cj=pbBsHFoX9mOsHby*%No_H!W=0 zD3CWCgVi_Td#I-ZU*E4q#)l_7EaDzK<9KbXt(VmYt>F+8Il=lTaY$|sDhWmF$=1V5 z8O)xI15s^wJY{3Ae(gQXDp6Kd&dIhM`H|!;jr>(9@t9#NlJLIjn=McSVv_F(zd?7H zYmh#y3YCwa{K~Dxt%qvl9RIwMsaxr$(SjE;or)hZXs-wM8nvZ`k>5Ud&M}{MV_!9m zTkw{C4$W7#5?xMD4w`0P6NgORT(+iBwBW(SLd@pX$|ct9^`rT7j8_eNHbCeVj$$3$ z0@SZyr@s@@IO{F#wC8tNcl2m;0@YMV6$Q$hB;pxV+X?pmzIxBCr6` zHgm|trez*)H2B7yFN_>Q`Lr;KXD^L8b~H#*P6NZmWQj0Vn>QjC3PV-%;@y#nPNlF_Sp?H7T{{LgqR6#ab5R6Ch_JwdwR6?^R7s|KX^r|6vWIH#3zJT8t?QCzJ;+VTZRt-3`a-zN+bDkBtZ_lX`1$-C$;WPBeS*Hu8%Rcl+Cy zCM|q8jZh`mQ)%tQPUg9L;~l}k%A8$wWe5uIzx&at8HES8PkUXBn5RUx#ya?jhEW!l zAIQj5*sgJwf}dxGo|BS#t{Ft1-#?4@Pf1jAfSo#FIE)!^!v|TRFY31a` z<}bUPDd&!yG$r&LJAQlHu)I>D0m=e91?<|gM$^y3<1SepyQ`>nOQc9tEEZ}u^c7Sg z(IM3|6&!;fdL%t~WK4j(Bb#Ir%8UM;x}=tqnB!+hus21F5zMAd6fi!qJiItz?7fJq zDvvO?Si#Gqoq1j?MibX*sNF614d{2p@8h+96tzZp`ehGxe;oHDfwiW=!|-t`y@kSx z{Gd_kfiwy~_VzHUD_bKx-iIY`d%TZF1S3AaxAJB|vrL8ecB@UQTgP{dq_r6b$D){}X+-tWdtbYgI^(W(}N3)~ETexVp3k zD}H3)(e2yfh|6^Xx^U$HvDFW5pWh*HT6bFq)yBVlPOXVgpCT=m+ zpltfCC9riZu3alZF<5)2o^31&giftcc$g3xl=8^yT*oY{iNSO*J#9BWqUHe_h-HT; zQaXVz9HY;S2%j|$c4rkOg*#hv+*9OE^J%6IEHOW{9jK8qe_6Sp@Ud;){!9W@ zCq7!>YzA(F$s2C{@NRoc)vN3QI`yD(!Ram(A}~AT=(hi@d*4lGq+>tm zX_nF*A>_G<@2f(t=;?+NXu&_y5A&q28!HSyJ|+b&)DKT|^1#WJ)9-5xZ{%R1CvVLK zb*vO8`}4Wxr}}2v#5dz}h7pWG4M&${xE1Zst+5o+y^c)dmy32yv(i7}IjM!Kivnk~6uQslz=3u~q=ac!&w z!K%NJU0;Tq)pP1(VgJ|0V)0_wRX<9&*+HadCAMtqa^8?t;a=}B?K?!NAa@;9CQi%` ztbq~tz47FB)8_!NSf$^K{G<>uue7!Z8Ef1p00t=*Kg;S#vE&*VPzN$;zr0t|cVF0G zjHDWD)s`@56Zmd+SQn_p)(%b&!ibaQ8f*PBZFl)^k5&uR3N zoT-rkm%8$;5|3I^2Rh1r)>_7z*|(RgxMCcOdqqC&NAyK_E`&_8voGF#iT4K<>dWm& zS2g^}>i%%g_Zo}=cg#0v{`1om4ESVCBmAw0s?0mE@uH{^nru%(HOL_^@~Y#sdCQK)8I!*X^wI6Zt<38L}$K;}g@`8U3 zMa_8Ap=h&Xu8PFcJgDV(8=d8i2m3g7o9BP2VyHJ32_@#t2rA;Twm9@r4a6^tYf8>L zR!hKn^{|K~r6X*b(+1-^pD&^~wTUG$yY#Q+dmQNtruLymgI+kIqUv=gPvu)X?`w-@7{A=pa1C;;N8fy{b6W5%&rS1GtN+)#ZEc-{@H4C4UeF0+@^x(%uwax%@ zc5dA@fgb&lhm<@t3V_Xr8ZL5aZ@9+KkvzhF)W8#j&CC4SIVrXeV52kjQqtFL;%4jf z_qg@R^WAQ^jQGzWGik(qTBa? zXAO%gImeDxi8qQGD9&uOSkLoU))2E)bB+uNmEsM4Rnx;R=lI>rzUu>PuNmL5xx(vj zNUh(O=cu@1#{Y_ul5)WL(+Gf&>8lZCN*X9GW$B#byO4QAw$cW4cBLhUdLU~2a>bd_ z@1OXeS#yHX+)5Q5H1zq%+{R6wEd^F@^Y}RID(zjFrB`jA2hwb2Nqua zqEZ66(b{as3Rl$?48VVxo>Scxd`*PTsoSp!QT$_&npWCJc%moj^7}y#=W370D$)(M z6m9~#yL8x^57ft`xG2o4@) z>*)F7dVKXC6z)hmcsRe;UC!6dwqn!Fmi`xn$d)kGV>Dlntne&BbN&+>x6N<-sF`j$lw9||=5!N#QFaT^7uKwfyw*yI;)3Hx zXt9o~%*Z-3X6*dph8>vD(tCOe1(i;gEW45}<;@8r)h6!-W>x#0824|r3! zDHG=h>&5up*vFroFh|AITH&`>Klxg5D%#_BJZv{ftm40)%1Izzt{M&>z3!B(L1L}Z zZsrYhmo?rdtc_JqcwD@U7iGmk2^uD8aQ@`wVZ3q9LzVC;MlXf(+OwCnMu#yu=hm!R zxmwbYEv&Sx=o{IxM?mgEhED|v+>+O$xyL=RV6EwMYT4aJy1RYncKS4&niBScewlsw zC}jYeaknSq%Rk)^tiD#6(f;i!-0=Gmyz{3f2d}hreXu(w8qI8(dRv`g?Beh+gNH^)<|23Hya$lof{UZti26VraC=nVguYhmHrdY8 zyEZ;_Me@G;^1Vy6G~JM+TwiXnvmBjDtW>+!th^fiHE`u9eiYa}7B)_j?3~AZyOy?I z@+79a0aB z(_me}4suvAGtaeKp`}J^KR}d$iDoXXp9DQH|J1Kf;dM=tuzq3gm0n_h&qWn`{b-}i zBqi`JNL}88d}-?PY55d!j`BdtxI>bmoZw;6|^xmlUrkJjZK)-H@=4@zMp~#E zdGgB7H@s9#Ba#m+M9x129pXJ8F=gE`!XirgOU}D_gjG3m($4pr)GwuSk-e|LCw;;! zSpeS@Iu|HNYqX;8xjNTt+K`q+U{lcFE~i=B{`2EQt>ERFoclFT7`tqcab#3=A@(5h zX`?L`_|{3^)Gi2T17(ADCsbbdcaGf+P`o zf}6>`wr!vetFZ11#h#!S#Fm(=Ij(ZAM+Nto^Tj3Emd-qQOB6Iq6A})6aT=hqIcvaV z6yv)N5=Jl}L4Za>7wE-4wDxMik>Veg12{tnX@0p6~Co$W=r_4eSS>*jBeb-pfVyuWEq(~f3a&~MDu zGBV4%PL>uFhkp2U>q%;Yy7rp}>H=1rhJc8Pos`k*a{MK%{6Fm#2JX_=ArG(;Wul$r zCX7dvKl-|4VSK*&3}k}h(G>^`f%gfCQo1&iZH2 zzt0K)Ip?;OT}xexpnRC(s8W=2w;c;S8NsUzs=6cT{(iB}<(RP_N%l$KTi=Rj?gE^5 zQ~84L4x-5dOb#j!qYi}+Td(z#@W^d9zTdU!3S=SNPj5a84^<3@6TwMi_-A{GtqM`! zAfC1DOAZbSRbuyKw*^&s4!?KVt3)47?lOn!SKXmaj^7M0&+`n!)7~)@xu^6VmRq)6 z)Fy?+!r-hFvnPZ#CG7}B{2HJGf#+g*Ure2I+DhuaLOPA}yY)MM$g<$L_SIbBGX84r zvoZRwR!XoBujiyrOuwny!{RcoSEQ0n;C|U|;&Moxx$d6~T(2E&Fqra5uvX#C9&62o z59`-Ttb8h1ITn9|K=A63R_BJgGK|Y$#p~*b;7-FotQrdDiHb$@ouCw!2;6q5RN*{Y zz_E#<%h~@>w;0ioTfBBQ<Ex3d9Rt`T695tFi$Sxqxbo*qU3SR+YQER% zD#@=Ct&^KW!0_a&h0nT(202jg9MOze6(`kX7Q(>7OHSx#zH8wS%C zl^_FRvs10WOZx95ET6Z>ivWQsrDW^w-L`sNJ$;33&kM54%qv;pC!a^IFdVZCq>_|> zPH5=Nda(nji;g?oW3hWI7BWiheNgUYGKQt+$+py`6*6NYZw;eH8%<#PgFlpy80&FP zNN*!A?p^E?O4hhJ=M3)_y+_CvXp&-vjL1qVN~we@bO{(b$4c%^SJi#wr1 z`=jXQ=LE4GIL6TkliDilWVRu+p|F~d$x1uxM-d%s#=;j~IQQ^xzAWF+ScQB|4)qh4 zxD_r(>G?@_NuQ??TXEcN)LEbPlP2rT&OXx>wcYE4%s{_XHGTM13Cf^ho^!z`{xV}} zM46-v2wq&d({45k$*-A!mH!$PYUjyuLHuT}F(G^zcdp0CkLK+NxuzCMK512Qg@2dE zUn3wg;vUQce1LjwPpAnS8oD(}>ycQgRFa>aC}wHm+YHp#$ZMfjpf{rdK@HUv?B%D- zlSgdf9)1~9z5W!K`+u)g&Md7xwIN#?#SVV0Zk_Vkd7JT^c5|5%Sq(pVeGgOG!vGFc zSbk3W*CL#Zx*OVw5+s(rAYMehotS*~$fPX@hEv&`8hJg_T)8{D7-%jyan6Y|D$EH- zV%AJ(~+vSQy+dk zR(aMdf-nQ5Ant3_q{tWETRYz;Uo^6D7F6W!GX6zrui{{5CDvMZu(Y0uz+S>|lC%hm z^O^l#K6Iz;0SLDk^}?!Ot&;j)hKpzr99Cj@;>dV|kfk(FihS;HN0mE$fuQQH{5~6% z3_W0NLCLdzb(ZV<_i|Xt?q(BkC+dFc$c((kssC%s_3~=<4OZ^aWl#CsDSHdO4+WT5x&-YiEcAWR z${tqOSh`Lc#kF%1o@VW8EuaLX5x%Tn@dvk|3?B5Y@)K$+B8@N5KK*Md8OIb&y^~1m zSSB%}zv_5BZof#IuiXBRwA3|O6i9dil;C9$IQR>oPI9 z_%c;)^Httbo}qG&b3fvoWSFdmCz=(&nmN&oRBJwmx&blXYoj%j;27CAO)BM$y^IN{RB!%)$(z_UP zq*b~1hx5h4e~H98c32KN9}p6D1Xx+^pa8Y4!PmBn{-X#*J{ic|JzY^Qacmg*rGNMp zY~;ohdEPs+hq`*Y_$*t>;#6WnCyr^zP zYvPnH`LDMMnt{C)APt@dfu_$O15knHKansh-z9l zxU(Ca<|3peJ?`C!W-S zLIk6l86l6Lkz$G$Ohv@A7t(dFdboGF#lLb-Uwp9Llg<4N`b1gSm@u&;1PCuqc)>ai zI$_xkr5Pmy%a1^~bR#=V$ezQb+={IpbzIFp1_GoX8!+)XUn#?-c1ez)zFPs8BdP=@ z5m`a;;>(}lpZQpXZA%>l1$w(CQxc%JwD59Qw? z=g5i9eSV@NUnyyqOA>Oj^m{35ScFu7AFQTip@fieUx;t|j=ipL@p(FygQi3|bF}B8jKP_Udem|Gz>7@- zMWr*92ncCYL*^JLmFAlEtr{w#M?vY3LXX}>$bVj4+SU@p_ioHT1z!_$Se9bRLu3v? z8 zXD)Lc$>enrfa*NbN3TUB(qQ&t6@GxyJ(bS8X-uH$q;@BS=D|wrJGzwQvLo&Z8Lssi zZ@vL`@LTB6FT@Yal3qQh|CuqIlgFWnS`#GQy#Yk=B z+KEQ-imA%e7os8>0j@$}GZGEjh_idl>gh?oD%+vabQYb)r%oU#g-Wb?W8@@)F-r-- zq;vTAtYczkmCIPcr}WEIFPHRNi&PJUcM`p$ZFPlz$c+EjoqF4m>z6~zC{T5!D9|CW zMEOE^36$+66r0YzTq;k$bVFgf0N~|YQ(nZXB;jsT`qX8W6niB6{!6LArj|q^d_QSr zN;?;dr>&Fq=G>&ecT7L%=We7nf`_|$LUchbCmY@v!F8KOQrE{l1j6l%?)_toSyiu9 ziUSt!{ySibt4kNjo5^eNVe6e9y|<9RMrL%w8mQKlm5>3M#2;ph9xslRHBu^_@qe!A zh3-KCRr@0%pb(8#1IScXg>+2fSJX+RJ={W{Yov>`N_(@OipuYY&Eqs=)_SPs@V``(oB17kFGl*)5B$rwdASh^~Yq*MmF?ui^b@cOJti3eMns@ zustAYVRU2zNN2R&4fy~o09W0j>h}>R-dNUB)|0ntIZ@xC3)w7vo?~}oHc5tYwfzd{ ztaGueVDayTc1jFlB4dT&)i1m+w8J_A@%_5uQuh-7M<|Ew%fu&*9(<+*DDe*aM>kb2M*#L zVy}{n(;T8yzgTmz1s*)J+!s504khxbm%w7&bCkC$rou-Sw zRNIE{wTG3&XK30m!9kFI$D2%ViCOi>Z=H*L?i8|YIm)@`oeCX<os;vFB===`xeFvS;w2Ut(TxjiIZBP<1R)#Mf|-ztCCyty+ra>}fV2g7_TS$~Eg93{#9F z<|81+v00Qohfbc*qphU*^EPzYj8xN^yv)a?efO~DsAIUYhI(O!`FBmC0M5zk`Ne|n zEb|{?e+*J7t`nIQ4|tMY;r<1y@4itc1Z-`RM0eV^d);<21UgTU1 zz4`ClY&mab%KhsfZdA2o1C9u_yb71Ptlo9!A9erM0S87N5NEw*+H=6#52=H>BV*RD zonIR!D3*LU^h~8bjg+J=!P90`yww3im&QSv|HRRF9#`HsK)(D$xn{eFJDU4fH-yk$ z{41kSvM?i|C^c< zI_V3|D>9ji%_=jZ@)u8mS=PVNJX^7#@!YW!+Pfugrf`I1BJ*j4MYlZQOCo6saiw)H zD3RvHv%^eUa-e}`9HD%TApzCmUnfwP8>leug;T>0Q` z;qzEd`O!qYgZrw#=n7oVG8Qs*ZMF1)*-qJabAYM*k4AUYQ&}Wtd%o9hlMU@%{VEZ_ z0kx<^(j9E@zye!VGglvZ#0x+$(f+%abyXl_WCF2oc*Am+``@Q^;-9wxJLrT(SK#0K z?V#5R|IK6}L)}z3Ez`6&wdLK6h3&PLys&kdq{gQaO0ePv6scR7_W&t)#O`Iapf3$I zHf_r}&>b~aj%GA}yC;C<^}1~)3NZO4rJU3~Gp9it1$F0Ys!x{*Qk`aBjrOh}i{Ib% zrC~0@qltFgzIe@S{^W(FLOs-*)xBL>rg{0E;CpK+n|lcnB5yI~lxyrK`?cf==}a-{ zOn=?p#7FHIfCvO2lI0jj(AEe@AThWe+ZqE@afOpR{cMFRW1VJ0D?VutV|B${E*yLdB04etUJ*=mIE_`e5>1+m!}pmEe^ge2Pa36{;;Qx-AYqRH@#%LE%=y5anBUrZptEjuF{yf zHB9RY72bER&zmJ3KFvH3wKan#&#KG8tf!osFeZ((K2`mD*T`bLz5eFHnT5xP+U^i5 z*6sZVSVU|wyqxiYlcgFHO0fznmfzX*VORAxTyu+8B+X<4cb(nqwjKT*)siFyctiOm>m z-RF9Tjdz$5BIlHCc91!$kCUAN)F;8xEzAdj?l-zZR$~C^j;VFD_tX(9D|O#dmr&0J zyFg%b%xg;E?|Rr&a3u)PuODnjo=@Vr9;QW}FqSAN1Q2~rB|Y+LM+a%cQizEve6!lc zpdNg$2p!F=A*)Z?K5Nbw=vD@x!w>l=y~FPvky1wNNd_C9SXg7{7;`(hKd#Y39$X`f z$wy7vsWex7De? zW0hSbva}Gt#KG@lN3t*GMlC6BPODJyO+24c>{9dL4_*BvAfysiTG+TzRc|KUP`j=^ z@6|8-hm7K%P2G|@OzW98krRzMt6O-JX$n68_ram;8AU!A6oxLVso2E(XYJ1#fcB2w1&x&74(xr4?V78M(W zX`?Mmh)z5D*w#a? zOt4&4Xyc5&$Y);|Fz3FvJBN<$^kD}ml%E(*Bz8VZ&Mm$*#xRmp{ctIVqR{8K&1N$8 z4F0L=4I&H-R=m+8Iuez(JtXT)Dit8tGC=uk&fjTY+17Sc(5Je=X{(t1Xp+@TnWm4l zgla1_X1|8x$>f;j%DIg%+&UkY1gA1!IDbB&S(tb!R*gKf|_!iW;tNeHeb z2Gqs!b94-&rMRjlm$YL|lc_p{h!Rd1vTMlufR7eTT(p}DNrc`~hZP0riN$>(pPy4( zH1F&>{LWK%0w}z6J%^PZ3keMi7>AF>c;Nbh-vPk7{)GSKCpAQ;(KaaSSx1b61vb3c ztguApKS!;q_50!6iT;*4*}<04p+_?oL6$|`MPN9@Sk~rR1C$@Uw!$7VhhX}d_oVM3 zz4IEU*Ut6tC?HHQ0Kx>-VM^AU;*FlPzk6wzUJ<%Z1tb9Rmu>9`Yb=HWI6(B!HNh2O z?Nf$R?;jGx7KlFgZUtnJGz%ZAj2fE`sH^-$&7fVG{|J!AO}B?iOfHm!7F*0}cJ>k< zn_bH!>7uZYVzIeLzA@SJJ;j}vgbgJv{G-#^bUxy(mPFLH>}J|}_)s~oyuL741oTTY zOzLRN2L^Al^9`%O1se5(VzxH9dWkE4|79VB&$$6E+VoR=40@6Y^hKQCW$c2IZxBLl62 z*7_PSDZXe9eW-^vi~7bOqe7IBgLPwy1XOJmPRSd=9JX;O3Bb&{{6j8i_Z z0NPFVGQ|E!JF#_zwGYBw1Msw%h3M51z^jhUnjHc#53cUg4wf&S;=^cfg(sDg7IhG?r;Q}MIJf+qM#d3X z{N-f&r_Ld_XkTgn>3PsJ2_9w1NTT}ukUKSSs2BWPlQ0f zI2usUL72)AB0Rz(5vv~E_mmX&+p{b zoiq1TAYq3|8>97ka>k=OhTt-9(y;E~_5sW?DyVE~?A>R;(e#cthzG;_(beSdl}Fd< znWwKl?5SekA14-z-oDbKy%q+Hu>+5fg#T%alHOmbRJAH^AI|Gaumx?}oDsayELG zm_QyCHqtq=Ek5!JWgD_cRRcoK>J|>IH;81alv{CSwLMlK`X{x4bxX=-X_S>Cc3{Fv z49s!UBb7{o*5u5Bl@1`OK(ODE5LC1z=X&~-p!PewuxjknUkFe-l+7*&_Jx@oKxDp0 zI#&)8c2HvpRF}eX!v!~KGhsn#iQO$D5U*j7JTNMev#@ntKFI0>)ZAx)yIKN}30yta zr&4d%l}NrKx)4s-8`0KE39Bn)2@a&>8s861);pk zKea_8_S&&35)TA+Nt+ofCV|98?oGVVIBLrKb79@}2#~kcX8AK~{O8=MG`%WkJM=>H z{n=yvw%;|CBo3@$0UF44db9FP9lNrWwH3-K=jN<**;jq1n7>HxfK~PN|_#2eKyIB(< z)E*;{$m%}T8}Yrnb-rjC^_u`Px4~QYT#0D`J-Bplo1IZGKscOH7o_2?*%Se^Y}hHS z2;Y#MO|!?zCS2cmc!#O;9~s9}2L?pMfcu_{51lX1*j9&chrm;mqY`gDrW| zro+bsyMEeUQLY|@DgfLckr~H0ZIRVy7O zEJ!1Oro%+5EXpsU-ffF}MVYD>pLG_SK4& zN+y~O-LP{kH#vAaP4g9P$wu#8aR6Ce9pj02!3z z-d2fvshY9Ah1M7{5fh~BZm?HQ9Qv%_N`Z$ z`>jCUoco7P_1;k|3EHCNAYMEE)uXAnVK+L{>e)qjDEq6J%-`OS0gU|b7AM-}(2~sC zlV(8m3VVN%Im|)y2512qk$Ch2ar-YO0%#}4jmFO@I@a`o07BU^8oc!swA*8=zD;OB zE6KX#5x-0G)B}5neT-Gl2JjATf;qEuOSdaP`F8i!w*T;+0P5HLATz`=HCH&dxYD;8 zGJY7`scGnci|4lbFT6T~7wB7?KxT4{ac#37z6U_YC<+_Gqsq7-JoD7Dh0%Y^4DZs! zf$SiWNnohkGPiNH!JvQC^WCwmp6Zu*s(5zNpfJaBDtZA>PtIsQ#`<);|vd%11J`4o{TwL!of7dJ@Og@OG%fnu% zl+Sns8nXA^cz{I_mnrs@8DazKS^@7qSqoD;14Pte2xleka?u8 z;X$-}D*XO82ZmoWLhKvX2WuLNCSc=g`68%~dLZ zc>~q4O^Rr=V)QO-`Du*&afZ9HG+CtKZVso1Td!_X&% zH1a()Z8ol}Ed5ZvR&_N5?BNw!nVm7vNL=?ZxBV zrNJ~eXWlpRa#GQ9Vi=C8aq5g1%%%QW0fOe`7u&al!}}VC=e9e`Yd_6g0U2GMr9j%H zF2bB5n>RfMDo^SJJ{J|oPwcF3a>9r3L059KoceDC+Cv9d`O;zm{Ja=GU2>aHF-ZX( zQI!jL({|$#GM(9S+^)p8-l0~rO(AFPh%sMj<+a&*vQ{Ma85;mX8sqY%LJLZ7VHug` z5GRGDwftVUYL$o5g4>PG3>Id0bMLZO1keM4{-fkNnp8Iu3>U?o6F6z}@d`8Z0uW~w z;f=V_Dh0>}Hcow}n%1vEbdsnx#@T5S@whA%#`Ap4JO~L0P-55wGMt#E{NQ-dP!f^m z*-f~yDF7&1=!GBKxoLNitLlMrw?jKKv&(-DUuCLwWxr_px2`MD8H&KxU=Y40Rz(s5 z^Zh4N(v*qRSqnah!>DoCKZCCf1nhYODoP%Skp(z>R5BIxz@EB#MQ|hF9MarY;wZ)< znQKrYh516c9(bllVBE^)aKK!LMGnb|NK$nh^V=#Q+c4g>E1s%9h8ZbOR(JN8*4VfN zf&4m>scigK8k1%^3FE3boCn`aQv;|d-k&~w#!K@L)c7GY-uQmIu8d2!#ps2Rv&Eru z9oFPbZ#wxMDOg;3MmFPT?F!f*ceOsdFz*0E6I!4WhuPmSp#`{pJkt=)hg@@cK9IaA zoz4tvv`cPcT&0hEgN-}Nz*1xT#4*bA_FKGo_6vb~e1cl&af?dv;w7fCOn=Lb&0g?_ zsuSIq;OqH44Ce~lrB%+#e#Cbk+AE&0qNi$}L0ef_?>;=+C{qV1j_BdP#vQp_p{MZr z2c$GR!nQvaFndj@GD#g6J|^8wi`{2P^rErWL&TBt?kdJCN3nh4m)rO{%)YoWTI3Nn zzLd>#dFrj&f6#YG6MQ^nS#*)0WEad?lv_b176g0e-z&skDbmw?FV`P40YkD1oV^G$XtX<3zx%$d zX>u{w_66+D9$~_G<7C!`90I-l!Yh*_|3Ty*gygLQ)LY{K#U_6*v%Jpri+g(AeStJO zOp~roAeL=R`J@`M&R**FMe`&o(B74v$+v-5*iQidE{2z5(N+$DwW8`O6w`knbUdfu z+%KfR7s(qTkp~!-Jnl@M4fJu&#H2CgBC_}?Px470+Pn9D$Az$ zpqiFioccCf%!-BDP#~CM!Fw!J$oMQi-49E2{?X;p<+L`9AJ5wnWEXXDHemrUKDLc` zeQZgbk66=V+tK4XJ^%S{5gb9Y2^~?qX}yW5&?h+#U0<^HSv9>GpC~MT-mXa1_n}^J zVL3u*m|qL#dsqaNYx;-+s?d*vF%{dT#E&n-JpwQRr5M&aJKGfHDSGBtJ=NS>Ja;H%N-DNV-PsPPkJOr ziey>vyjKNZXjc}0iXUdirr5s{UcXyr62A*S`T8DHQ(nN1y25u{&`Tw@@cu9ZR4HOn z$Sim`Oil>|3r$XA-JaW8y|G^3ED=5B?egvrsJWO|eHus&E0#@r>qMZ@9X1J1w0nJw z)h6fRE$#Y?A%iM!Hy0Sf=efg?27`Er%~La@Rs;XP=)i)>1iWs_*&6}CiRKnlL*Rs` zIkaOm{FYX_^w+IwwUd|nZcm$iR_zo1Alihzlt(B{beK36f0EDJVg)0`8 zEnP2J_x8}}Q1QC_(9NW;VjDw&tq^j>3Z33oREF24z>lK)So3MosJ3-5p0Ww+3Jh`3 zyT1Hpy&4s>>}Y^szTWcL;(S*E#l)1!mqO+r94^PJ$pJJDO_Xm9@f6--t-!`&cknPqmK?^i*7Lm4FQ-zuf;~gYuU=I6l}EF%0`Oibmd0Mt&)p z{4{k&VZ(!#-+sY+d743v$a0fYDsgf6NKxSWie+=;{59tDZDKB}1lS#QkM6V)kZE^Q5A#bVt=aOqUOJqXVeTGXzEv`; zVPKR)8*hMxgd&!E#8tFe^6uBW5?f%yEcycw3!KcmI8sTaXt7zHpoQ-*oxkpXi?zc1 z+4u2RVy7FLp|by-I}vm#23{rWSx8Ay~aTq)RFcr#-V9xg_z)0YCsvlskpmT z<+xBrW+cZF?YAW#-BbUZXytC_OsWuxG8>|F`at-9*3J~^23&R;X`+3)Foe0JRd2%M8yNY3Z>XZ6<@=i4)Hspo^=`mc}*LeldJn zJe=%n+_tNZ1!?=(t*N{Dl*(zcN8*K=9BdP}F)LI^vvJQK>~Ib!|HR|x9|7h6$>+{J zD;Y;}EyKHn;Pr6ue_TK{+~%31Z|cLd=|6a!)uVq-2JF1e_xoM;&a((r{{3$Nu-U+( z4e83CO!3dYad8&ofA#~7tid8XiM|sezfybq+mrv zp?+VuK{M-Ai3)xtt-j`uXrGyHQ!>=W)&fR#4pyGlo*teHLaVD(J22RLv#&V0=l|rq zEv?5!vgudH{c;hMWwYyIFx?!hocBQ#vk0h#aHMGN`7erHZk?XnzQ z$2u%E6)odiEZR70;1O=+W>Gp6y;~-=kT;d)4Q5UqHR}A30xcvD&l%wA#C{hyd3Vzi zI{?qh6+!(&&zi#C7N)q-QuR?PZ>?tdf^i{NgrdZ6%s#HIFwRE))5N+HzG*FyKg}qm z_xGhkldh7kEtILE0Qu=>%xE7o52lU}QCH}s|8wCk-W*k;d`s8FZ`I}!l|{o*E}qz< za|+$R!gf%3?!?r(L4+qZS7e)NBmY}zOV9hu5-Of;d*pg_@4)wn<9HY{OmCCXj(vS@Q<(hThZE4`+b>+H^m53U%f;p ztnStr^w|KsQRX+LGJU}ZRkEE#=uX*euCzW=Mc>_>ZWx!VvX$*FxQ%oD(FIo2_WuF_ zLe^0$*IpLcA}Pnc@|vL6WUi>~OrBR+(+(5%QDCRWL>G3+Zxox7$$T%wGLz5D>I)ia ztagvQuM_#j*byI8OPxjO!Uz4RE@cz&B*w81>WDfjuyvbZ;}baY8$-5f^@+vt+pz6U zh0M}-R#$t=9{Bs?5ZUq4D)WrqN12HCl<^T>!FOr) zL$P9ErPnN9oBPzaIOg4s1TMUZrLT7!&9LMM%eboDARZA$j2e*yHYm{0?sx?jwC}EC zq-rhkbed}=WxROTSo1Xw>h@kQJt1mHCV6*rG*i`SlfUy6vF@KPmuJ_bhAEpjpT8~t z7eSEb|4DLmvMx6EbCT!WahGh9nVQ{h0!gkv3HilSr0)v&ju)8W-$H9G%`7JLW#(&D zT;qr^9JeS96e{+t22c=>pXT<^p|N)cPW`3J_!Y&(APfQ=J&rrkj5#M=If=Vs%=S1< z_Z^``X3DnvU5o4!RhBkc$?*_hN zkp*MlBr)dm!Z4LHcEi>8KX&z*wa$euN(B&pU%EYM5|?d1wi-EMbO#;~)D2z0?|D;~ z)xyTphf9WUL}yQ>S;pfmdUNLdQ-52G5a#>-DG6j0+P1sUf93p%oU|8x^JV@WEvDzE z+AaNjZe+Wo4+Lky-}km;J&n~~&g>)SePv0n&C?+eBI&JrW{D-jz$T#QA#(S_dY`~$ zNGRh_pM~T85tw;>Bkyyx;k}NZxM+*YjDx9Ya!}ehh#LQ46U&9BN))*woc^56<)@^w z?Vy8tTD^#tNVe+x!*L7lb?En2t?XT?S)YzO0io}z!pzEQpH8!2)6Ss}QI87^OXUR) z1HZnxRnu?lxTBjy_GgyGcmXu68P6t=RWgZG?kw%xCyvETi&n9Oj1CmpZw46C;a1f;|D)v1L}1Y6s3|E$}8F>zz+ z--_6#lsGrdp$3fuyin73MnHIWNsIlS08{Q~1S6jCo->=$G zNE$@itC-r5x^SCU$mMqs`;PXiaaFluPqfS;UFr)rXr@AW?>bfFkpIHC(={5JK&^R= zZoE>vWLVH0Ke)GYfZ!c`X6yK(4&UrB;)}$txO-8c!7DR(Bm@%ocnJArZq(5WO?R&*mVii2W6kx*S|}V(=Hc z8GHGaC^zF164(WySe6DVVf}ezHOx;qRnG9c&Fdk@Bu&y3p~$Aq)$-Tgx3Y{m(21Hm z75dhytjqU!jxXHU7#hsFp|LzmA0VyvHTWKxP?asmZYt3ra9aIIcW?$DKfPL*HB7)A9jFw=t*K8jzJuTUIvQ5Na$^8H|Lt=YeUu7*w7~9F}q3eh6#3;odQ=7(p?< z^Z&ApF!$^K`B;%5)7JM)u>wYtx&6*3@LQ0jBkE8K*EMA;7jKrcH#r)=U-Fyfnq7Gs zx1Hs!u*uA#lcxKm?nbJ&r7sKj7zku%@f-!2&R2?UAMme-jy_)}mk}oXiXTbDiJtdL zVd4kX#f!v&m@-TUUks?sSa24_it=?GRWDDSO{R4;v*5CePju_;$1q!~-Q|`k9wmi z!Oy=XMKu0M!AQr@GYzi17VJk=UogN8NGchw-qJei?vz zm|J=lwCM?2@*<^#Tb|}uNL^3LGh~_ym*n^vCu49;S7~;xJN96eiBLJDob8O8*WWXZ zeVFDI9mi7c9dYc|amHCI(bs(KMxVLuF@`l7usSmG==M7{_b+d9t5)<;=91>47t%56 z4O#O4Ra@aKviR$T72GHbl;-*S!c3`cnLV`{_=Y|lluV;O1$EIY1n1#m8pA|k*Apgn zqqt;`NA25~Ef+?St;oyG+xr!CaC|uP6L+uKGbX!6nK@cyo#|9=g8~Nrr3?k{%;@78dN4YgoqlU|irSTk;=ld$Yl7~P*E0#_@--f1RteGl zbCv%Lp<)c9vI1BfqxRbYgu2$6CCTkcz%jjgs?2(ibzOWft<%yL$-k)-hqhG0h!%=saJuqq@JMX+G(qHC6b8LHzTm>zEa+Ec%%XlNa@2=C-PH`MM z(`C;gpXXm<>WeYV5QB9B4=zv?qV;giO%Zr%EZ7Y&9IXX3w^+cR{F|MWRSEi~O!D_-zse_$;^SecaWe28 zVH249>Nb^*UJ0)xS<+wS4k&vHf^t8eY&jYCOuM&>E?M_N`K-^GP>V!7uyBY*9W{rJ zdV#`MZsYtFi@W|~D@GX~cl<<40qw>cY0r-BHYpF!Jyz&M-J$ruRYg z@c24kKQFGodlK9*sG1UC#r9oo!R;^8tUD*tetLoGgo*Dw#7^gVP&j!dtwBJxTlmgQ z3am7R(Dy!}6SB%g8t}xVN{;u%U+k;ZrGkl(-y93MVrlPdA*0N>Gs|2*A0{ECk=j$T9g1@hlnz1%oT(P}{4YwDf_k(zA4&K*7#R5G!Axj_pb zT=`jB+iRgS`P7~383+ZfL157^XkxrJ3!rv|*2n22^A!ajCauY~j7l25D^|E> zt`vQ;{8@?`a=y*xNX?%_LmEJ^T#lkzmfD74`9V|r*wSvrO#%MqpzlL{#!t5~fAYP6 z_?7Sayc0f8HKoiqI|8MrJ4kZ#f%ms^IuzLH8N^m=O?VrbxQmoO;C#KRkq`ENo(`&J zzA7F~{FY!2{iL^ORxv`x$iE1~i=0Z^JZg>a{(8 zU|b+wj|q)9(Vx9&n++gf6OqinBcoN(Fp^|DPw8ldGwrQ<(|uW6&EErvJymf-jsW>Q zt8Ih{w9e}hX%$V^rz8Vp+GhHcexpnF3vRod0s75f2u$GXfqzJZJ!aZ zLm>Zwt_wC*6{bX`I&>QyC5rCkcWfW?D3_4f_qY3<;64q#VTuhAA!~y zP~+U8Zl)=zeNcEYwL7h)ud(=6wnnF5?BKJwsk58;*i(r>`0F6;J<@T;SFqF7P@)_@ zU$(1XW_b;kVu&}@sen8+Vb(86`oOAoeLe*rSfg=@0XZ*v&LsgE=-FPVErn~j61euA zLGJ4=KS0|XC21^TZ31tz6=}hAH@ms+zF>b1ZA1osxlD^q+xm}}KsFQwXX8jm0bMr12`7?JBoj%He=ce9~GxdaORkC7FPyX8J=~Kshb7W#O$^5g8 zz^oPpHMC%Av+0%LN*lkFQv)WktS*)FfoUZyiFmlFy3MfKuZm8GXcG4KDGhMezAdx2 zRO#GL%9RpDS<4uPyGLWK``Hy^T{p&=`i8_~bYz>?wB3m%XZL1fz#Xh*@R9PvwS<({ zA|QhS|?toNvr%m9+J{Mh5eceDBhs$f#1{x228v%PvN_f66mB1b3KS)TV1{ zUEYcy%;&CjNTODvOT(BeZ=N;S!$E0!@hA7(A0wFh`5xqN^iW(aCCo24D2;q5_71Ba z?^!Stj-4Q=b(u=>=4Idukmt=$_S?a4lt3Ww#{Qd^6pw%tV!@-)&StCw(RYY42KbYEfoxB6rOa$Iq ziEu5&rOX;D+6=$O^t6d)BSe;>n1XKt@ba2%Sn`?_97|73r&|OJwQS_hLc9~*k!`F z$}ZUcB_Ttq4U^Cfo}Lv+uSsx|7w1h-$7Ecv@e>cLijY}rK;9A3)6qj3lGWpS?chz?ABYV0i$}0ZS8sTHI8h1ivf?xv!#Gf zq|3-B8$cHss^!!s5VBdB%XAmFE6%vfIsdfVL2fC}Ey{-W%S^iZ4%xlPrpH^Ewdvv7 zO_fsue(K&okyL0g3PvF14CSQ^mC;F93a{0n8z$?e2-q`J! z-TfI(K^*2?AR&g?2SOkTQ@2o;>Dp!3PoL^qqk~jRh1JyiE98>@#cIsRwPrP5#Qm4x6ku7EjLa9*RDBhVm%B^@h-NE;4pr0 z*Qq6ZzgfsEo!=QtvT1AaA z8AYOe{I@`qkODQWf5g4$-;9lqOKv0!?9YT+vncxpZ|@j7BsiqF7BTY_`6!HFv?)h;bnO>Pu$Wle z%$+jx200@CN5e_d*_QZ|iKraGy)p^_fyr+}rA8AbDwBM9kZ|GY-%j5ju`LEIb}@ZG z6-{w_^JUGUUd$IcZIAD%YTPD}ojirYwiI}mZdVQV_Rq{;r#2GXkH)3Whr%oA>Nm+l ziSj}n3EC}bB`yzOFPAEq;`5zm>1eP}`N~mm{>sGj$ct4VF7@)|LW{#{)y( zg6G$%!j-3~g3o4Ee#=1`g_74W13~JjK=+3$`ro_p<}8>q&E3bMQTs@JMxze+$%lNPskATgN(nQ%d0rX4?E;diDz`OUdJc5fbGOI=U|CmT^04 z?51a&uP3a3#%1}e-bvk$kt+=ZJP$0pu<20&9WK|ay}>qUfD+okHt2)~eEZg9*>MQ7 zJpn+9w)_1LA8hS8=WjyGX@8(K$hF@-OL?-~(6piZXf(|7EN~{l>V@>Q|McL;5J+a` zyy8}8!lD{}{Gy#N95X2d8wd%i#=IISuuw#7$57Eb%f<~31DWDOa%8)NC&o@yJahE= z3knsNj^VA2z0k%t&E(*_3Y=I^CMIbE&8E?&M1B#fZRVAb!2GhiXS0Ur%^nkUP9*?w zfcq(p2%*oJSOSP)MtjXA_j#zszOQCVE`^lg_1F3w5<$Y(D(S?IJV#XVTkWxTCd$)x zl9mjt2sFCIe^FgHI~HFm-XFVnIx|Px)n_Pwd=zh_{WW!J!3ob+5DCb(x#Nd+6r<$6 z_ucd>r>H2e9cgkdcx_Pbrrx3RXKR>W{AfQ1od9zo;R04E@n&+SFO#FkS%YI)Xw?N4 zQr9Xsvl0Nw9zu% zt7a7Sy{4jFapARUeLBI6mZR#mcX@%tR@NM4xRAsT8RD7%Y4g!lI^MJ3Wz+A5V>Eii zP_jpb079rWukqsVp$1l2IDOUs7}2=n@upOGBKBk3xy_ zR1441r=kM#+w96xZ}^N2taRXqP-x*E#!XS0!0$0fe9sP{bF&hX_W>zEvs8&{caZug z&wh?EEje@CO?41EgKPFGN=#ZdqL;nQ+Ag}~#If&;s_7ntZ7sI-I5JdThfZU1ty0Ex zRF{S~O}3qq$zQ=`dF>`o@HCZn%21$W118l1TfU}pTAQC(O3DuJ1tJkw>?WL4VU87# zcvMr?FjL56JX33S|Cp__l#fF`L*Ta^X?PnZxU89<@K%@!GguhIx&n; zJ0O|7-|+_-a6&ebKr1g6%z(_HDYruc_8b@vXv(O;I;jj8874xRI!t>wDk-b9KrsZ~ zOGR=&;1r_-UyM8!1|Xeb@>(vu^&{6-cB21F^wb_`ydZq=PRZr6AZ6Bc_|0`H{+86y zPk(+O_XAu7_IH|bpIbxQ6y|jWCQE%IJ&l7hg2jtIwa&~5<$SC%*I@B3Ebi^TY^MaxUD7>-Wc*Y(uy1etn&mxh*&0h+hXDfIL(DL{@V%&(q@3WDQy~ z>{&k-kN-)YdD6o3ZXc|!qVpDI{udvn=IKRnjlX>VRdFXGXNkxvC@^=G8PJ@g+FLwi zpNhJ7BjfQi$Ve~u8LwjbF8=qGfUK&k@npc%svqz0g@#sO)9yPDwx(iNjGjf5OV$gk zmcn*Jxn=UI!hfj^#dsR?H4?AVHS4ySQuL@CIPcu{UoqQ5UqAqUg7r&Gc`?F+`I+q> zv5y}ts56AYP37A+e#Z9Yj-pS{8@g?yddH+|8Gm@J*Vvz{fP7{?`=0pj2TgPP;}q?) z;~ZJ%rmpydsj9*X6OXi&`b}rew1m!mi60{aZaut*;;`H76C05>(>t;@Q{imbuAa5K zH_A}3sS;u~W;nKCXXT$XqN{YzBFV(v>FVV&`793+;N2a;Z*H-HF(J^ON;QU0H_wI# zitzFX;g_ZLG|TE^bfEKu6;x6cRtVH%^Ll!d#9Mr(2T z_G6LVfoFVlf9k(n*VHaf)H_DAsVne4JC0jxuhdOs0G<;tONn#y#k~$yos&W#4YiOp0SE7RCSJpw&`1%n$*V&-0D3I|< zAWN#OccK|J&r_g(j`Y^BDP*-SyPN%AA=`DtzPr6I26e`~YiDe(+G;+z4jlbhNb4%gR z)QA6cv#mq{8l1Y;<@G^297)pE1|JBJ*2M^Q_o9XQ2<69)1dMti-IPmks#VS&Aeji4s zzoF9Cf!yu=R5a};Jkhj>(bTW?hHnFou(T*5=|gcvzRvAW=XdVgd%5zUO5r|h-Y(qgDZEBip- zjoN4fYl2Q?vz$D%TVlA4OCE@Z^Pv(6{EruweYh5CvcT%`4l2vjRxRr$w|BxZh>ITB z08g7_KlAE88tGFe;8`TBu$P&8ok@L}WWjoFIx=GQjLurK>7G5_W*+l{gwlAaN;Qwa zjlA=eA$^G|Uq|5K-%4%6iV;2Im3{y@LxU&me#8_0^;#2^zeeP_54~KCu>DN3!pcLZ zQ9$~^d)@~q0Y7*anOQ|5oHx7)R7GO?v(Fve-#}_gskmQyaWV_QgJl4Qf8fmc$+kOH zm!Q#p@W~h<9h*p>v~HPE7NpS)Y>n^Y;;!^CVN1%bk_m6{Z32T-sA)4Zz8KNQTJ`;-zwenFdS!oY$;qL zFKp$3!GX~3!CD2nChX=NZN!+h38-`rD~f3> z&oD>pOTR>m8}o^;T*hJGTavXo9Nw*57wSyaa8UY~xf^d!O78Vr3Cd9q*b?P+3lw?u zQEKBm@6yO5U}@;MQ>#4p&fe6-cNm9bEYy z^vv-+7`e=J`f9eek(s$8bDh=2W=23l$6nOT?&(xa5kt zvNcwSlbB@wrTQ8-* z-U1ONA$BHI22D-Cs}LFRc#$EskSi4RYe-@;j@3E<1VM6_{&_`+)={e%mHuff2>3Ll{Oad%9;6F`!Xz9o)xfP5Ea+o2V zqKXAC>hJkAc1^Y1X}T}R6KZed_-&|RkfqGt60e2pFx8$C@dcaUBCf=4MXG?bPw?r7 zk?WJhl5}lBr|C#)G$+sE{p*=lI_pT&!t--xjP@XYA?{4F(cWLKsildO4s;9dOkl4o zRwxB=vik|N2kO|PbMcW@rAyZKbggC0OU{xC_yBmzE-S_5l-DMP9!y3=K8?nsg-D39 z_X%u!#^;YUGwbq-j-n&drr&-qn5dr0Iz*LFnm_spEN;G<&*_rpUJ}BluDnxj7*{EW zTgsM`v0R|5T_n6Y`Kx~?ilj?FD$Dnl=LucHqeT z6Q?rQ^QI-W!gJFUp;$ohG(B;@`8K z-yVEL^mAbXAIFBAzf-SVeu##yXt?wjJd#bz>9@H@497PV>Y}!OOBy;7LFW{9nKGny zP}eU8k~UBeCRbgt=6|`_yng(2O=n*h{-aYTRHYBFnBk$-KXdeoEGZc%PdUthcKW`w z;nkM1I{?cGsY>&ekuX^nH84vYMdjGO{65ArUU6k28*=oU;OiwqT?Rhe&xyDj$7a7; zo6H2S9VF&d##)%@(%r4*cHk}9G`*67p~xYs-ojjct?J0#q-)i`Gku*#*t3+sD3+T~ z^q7o`o=BfK+`pW6CwSD<6nrqn`OZp&87)t0`7R*;{oc-m2?PG2950$82cyz7Kmn3F zDrVHJx5gvC+?xFnCGRhnb-Q*V8c9Yo-Dw_JV;g{-^CnJ#wMoaKzwb0$F0Ywm{hnDi zAZ-^9AnT$mztV91V~!&7G5uVY9l^g(ArSD!>`6>#M5=8r(M$-4&7Bs9Q_%?3<2O|W zD{jnb=@D}!f7)gKDT7FJdS``Vm2Jo;{vpxpaYM;5W zVwZT_uL5n!$9Eu^j=JtSxx08-Dui~{ovCd$?}yEa_>cVZbyvGNQOW8%i3uQ2mFB_- zL9Aw~?YfkdQuL!Ql0?pLE*g?L<|J*RRuGTcN-x+WZPVp6u^+aDRzk@81+X^1)cp8MX!;N&uL}H4T)pqR}ARgUs`CNmxC zP+D~2*b)xce}K@)CfHi9uO004mZg-o6h7%XKEyVxjAaYB{BXiONx$?_k-~4k)m?m@ z4;#5OwAiygB=RTu3CpdoN?xVrs{h9t-g+;%!9Uploy(PLW&K@swySaO+9NFEJK>#6 z#+7x;Q1Y$>%f`*tGe%0d`)?Bpr}ETn5s=84lQ$i@MYRD$2hFF6HAmf+m<9_*dQ&!#ACb5g3i|7hd{rD6o+RU>rjRwc@p{{1`yZS}5m;1;?o73C+27$)SM%7|@1sk#Q7=Wt)& z$k^$vritkD?Nl&72wE#!(VH)tQMy}`xsCaYBdE-)_ji(!?XA>Y$&gvGi<*yAK4-9d zgpL(I6$x?FO(wg;sL7Ea)z3rs+!hs_Jm(uOV493=6@7eAIKtfjifPf>&DAa9g?mS! z;zqyvDLZe6j7G_1oDUEtY6mrK7BGDc&Kg9Yp6VieF*?_=@r_;CKV08`2KF&N!lhBq zagdvZtsfvY_jWJg-evuw6eaUbi!7&+eqz|Ui#M#>n@8xtEBBAnbiTygbE$<^58 z5{E5+5{8PaEq`pJC5F1mETpc~&mm`VD|saf~eckDcM-Wn%kUNGGL zZIw;uIOZ8e@oqd7_d);@Ggi8jL~slTBM6F#>`804JY6%1`TxFs!yC?DPrFl#6$TWa zOGpV%Drn6YkW{X>SJv9TL{I5CK%R&NrCdUumo@19N-AOIwtR-x6kSM)E+oqFVu;aq zchLpa-$+9`t6N zO$kdZ{M!LFNKj=Xb@7hVOnoqe-&;Fu&BA!)^gJSek6rIBo-t@gtrn1{0yA2!-*mOK z9Cq8H1)r*a&=Y&U38atZMx#0nKa(%~r^s{{n8A_XydL5Wab1Yjc#37FL^oW(ytlSm zNSew#(mt)gn5iY_v&p$DkCY~)yrW{Bw0q0lTC+4f$~(y?VRc2=E=QH`acbffLuO4# zSMtKWH(^nKQ1g7>=5^@JDD5J{d|jG$uMu;lAYQLnRm6pSXSql^Y{nm zI(&_8^OXHVFtLZ>Ue$Kg_>*jvkD1=JSzzEu;4Q?w)4^+BL0fM>pqDk6ETs$r zhbx#q_~eRy*sxs9qr+V&Y9$MB@*B(G=bBOQN)uZ1VKefJh!g~P3>G>dd9-^buJ zXaBIbr{y<_n3!6O;>!*%^(J~5Ip!@fugm#egGzz11#1~C2)fA-bX{G`E*ab(@xFF2 zV4RKOvXWWFZ!Q_Lenpz~5Si=`cD8i+n&`7$)SV7&rPnyf=1(r|uCDmS<~|Uc`Veuf zlGP3aK8L7Y9#ggUIm&&8^HqW};2_yxUO&6Q4_`uW?7#_YnlwB8hpJN_@ddWs>`iiQ ziS;~PD{-d#zB_b&e@8!XCjI&y7l+-$H`yPdUAJB36_dV|D^NBBHpqNQwDRbA(r+5~PEQJ$s!br;Cn+UPFe(JwCCOwS_)n8Jx9Ua_pC*G*E z0-iX8lLC3c)yS_j>a$qOD^GnqWB2C;avr6N_WzX0JwFgZI6nr-o`2ZQoiWHDo{Yl_ zj=7JSNJ@5txVyE{X5W4x2-#2Ip724M-;Bw(B?wh#nDTnunbg7PuLq7pbWwErTE7^K zQ!bL(b5K@OA%104$;8|EGis&A$~$vEAB-EGfxFl&W{vb2k_q!SEVE%&TC6;mC-Q2g z;nkhO`egv@NMj->KYt-+iOg17ejHHte!hjIa%vA(+FLp$4=P5q+E;mMmhZI4Vv($| zarC|5{XFDXMe8hXk&yH&pxyS-bf7a1yF41cU~{jOz~$}8m|FM-kl4{>E?Q=IM*QRz ztW1$9SIYC1M&^lKOgzRxRlwIk9InT1s%!nrr&>@EW=k6=l^E2%}c0jj_H{g}#x$&Bv)wGQ~G9Odo; z4{W8~izK{;=~JfPtI;@1kM*-E^GPY}MVXtGPaF+V&xQF1CqzpajmH#EY~PN~B~$od z>Jn*8;)bRfD=KY8IBbahWA>E73C&2Xs&vBZmSb9H6GLGm2Voujd0qE0l!!yU{q<;2 z$!}j-!#_DqJx_$N>1z0FI>~0iT|OQRL`^Q$MZ!k>!r1ZNE`>0U zkK-*Zt{?U~Bt1D&Jk^cAYUg(B=6)<|w852aup>vUeM7~-N(4mL%3ohnZ~6LB_Tner z2ub0XuKs0VXcGvD;%L0fk?5u}-j7{s-2T9ikLnO0cOL$3V%c{A)tu?J(i_}_7s}$w zz_TlCQ!zZ~o(cOH+&*REQ=EF2=1U6i1d*(FUTIpd-8c&5n1rh0K&%&J3-)rDv`6SD zHza;e)xeK2&zC~iRxnDEbb>V>(wI1g9&DCB$Azli2d=AAVdj#-?@K85jQ(b5idcuA!hP7h>}V;uKJ??GLy}RuTGvm0h^VO*RT{i z7di>QR_(=NITUY%>Fj;nI{utN!x)jQ9w4f`#%3s0zV`Zs+fFeus?j#g+*_|SX2n4u zzhZMF*_60gRuBFmRY>_B)D#2HCv^S-kA?dQ&5Er~Z$pXvp}2Gp|KedBY(By6E#!w7 z1(L|_#E=}Y*(Lj7_aLbeDRHuA$keT`*lEaTDz zlTAmJl1)>Ookk60SI_RLQ-3FBHPv(JZ`Qk(0pQsY4#xsQ2?$Y_GiaV80a&D@G_w{+ zQ`Glhx-5tpC$ZxIiRUntLgr;d?p=;2ui3@li;wE&UI9-|=iXX2hHQVB>f+}cO|bL` zwks)Lwjf?p(w16kz9N*+`+1&*BAE4^7i>8m^ za;i-OogD;UyA@9c4XiNJtr-{^tnpvFyPC2!Jro7dZl$id_{0Vk>|tR@UW#qH@CSJz z!t}EDEAk8%yk?sIdk?o|koi@qW)VS%oEnjyh(Wv*XNF1xmJ#hlsb${g*VhQTh zgTZnL$ee2?pLlEgk+ZUW7aBe3UK>bndTvIgp+jBY`Y{Tx%U|b#t#D8K7P}r7v%HY_ zsk9|ds&=j}YWe^ryiloq74LnN-nM_Me7`qe93j9hd|{2U*ctVcoYCN(#hPfUx#Dv% z9y?~Eglgf=$Jz`C3A`kfyi=+APVl-(_j&WP-~)AIEKBUY{q74&4c3~Fu@Cn_8Km-_ zgdkDKnp@a!(;A;a$slyX^A1VllUhe?X;9S(J#AcG8FhV^8;#H(RzU8O4p5?|oX5>} zmtBdhd_>aFTg?~gEEl#F1b&ztm@9vs!z;f<4i}-uH-1<{@K&4+pYUl%S*_REe04x4>`1$&0z|ftoXtdU?~^2DIc?go&Qoe9^}O! z((p}I{avtDU*!591=yy70CANQy+Uz&)eW8X}JqrV?1$*Id$ IO1}yIe}jHRegFUf literal 0 HcmV?d00001 diff --git a/dependency-check-gradle/images/profiles/retired.png b/dependency-check-gradle/images/profiles/retired.png new file mode 100644 index 0000000000000000000000000000000000000000..f89f6a29c6b61beafd8d2f729085fbf1d17b0e86 GIT binary patch literal 22003 zcmeFYg;SeB_b3dM7AP%6+R_#akl<3>9SXtS1I0^mw?fbsC%8+o;O^SuP6=AH#Y52G ze(C#@`R4l%?##_hGP_T9&z|$_+2b3gsx15b>AR;G7#PpNa?pRRevJ{t%&eMKgHUcYq&~f zG}!30jOy?3Hd4!_7up%7^#S+%s&IZsI0*K79N~yw;yn8u@QwwX{hve-Sn)#TtQd|&0oD7Yr`p5l0P$H2bml^U89OF zx^QefDl2{mvw**mQM5^x+&toGcwIQXl7b3N;`}Mre~zEejRm}1r>859V~Y?jl~HHk zFqf%$c6LbR5`;FcDoQ}6mv0e9*`>Wzp7;{JOeNs!7`cft{Zq{NO}j)>rlT(JS{{#| z-o$?tmbN*$ccL0smCfDB&82s|wx^ni zjpFD%JyZB_($YS=5F3xP#v=-6oPmnpwV$6lhi`br9ir+eqoz*`;smu97S=}#X}fzo z)WjaiNd`ufn=|~0m3(HBX4X@3q4@eOjeI`B+Evr5hJQwgAwFr3T-I~Yn4rn%^{GKk z)7hWvtR>KFbla1TETl`_Hw(DSPJ^iMnjQJbrV?6Wvots{`XSIxNPY|gaN zU8JWnU#Jf|xH?3Q8y!MT;0qm-=BPXleN^jYY)fvncS6hp{h3H~3CY`<>W*qZZCvKM zT(i&ewXP}{k3e?H$;Xf54~T;Czl2t>hQ*Yc>cCW(pE{&IGfI92u9W-DRwWd(_ozW* z2C`{w>>_Z?2;#FtuRwv~zqIje#NTDfrN|vv4&5c-q<8y9j!U(EMkF z;6wZ0V|E(Ae}=f)h|uUNsRE=NoGk#{Y}{<`X+)m_003cUb4x*W=@0)s{h=p9^U2lK zQIMV8!^4BkgNx0<*@~S*KtO=~JtsRSC+ouqRu?aOR})WGdl%aO0`fm_q%B;`oUI*Q ztsU$E|KOUKI=H!t(9rx_=zl-|ji;UC|1Mgay_MZKJAwNtMexOlM z%Gtui)xlZQ!NFGaA8OY2HZEo+ju!tA6lVYbkNEE;h1vh%@&Cc=zli?N(+8?WpFYg| zpEoG_w48XC8v_G?0hX4~^u*lD#K~Bc`Q7jGmzY@JADhIRhy_rD8yI?0@<9+0aaf|3 zAM{;Li%=q597bwg3=9BJXktqgg!zZI(S)i?;nM`4>|Wn0yC>b-?RRZBH!rmNY#yg( zF8kdtt%!0RkKB;S7pTX)4-f|s;$mYR$B2(#vJ-=_{;Mwyz~%11`A@r!C;;$_7mKv_ zzy89CI{2>{b`N9fqJGF!|EC)$z9#e!PJlQW5iXV;t)m*tf4YEQ7X<&F0)BnK4isO& zHGGNxpY8+rNB@-3G(cKF*#xC-P|0soYnhmx0zrca8=TC$$K`T zS8KWCi7ZI&2o;liNjU%cfwRI56Y#M=;|AnT378MSroB&hPTk~OH00cl)TNMGMaOtI zwU*;qw~UL4Rri6?<1pz63!6`JZWD=sUoD=B6NBP87TBDaekg;Lo%-$E2!gNV9?S|E zQ23O?p_u1UFKMUgb6E|9>= zT?P*A^`)0fj)>=6P~2c_L8zz9zIe_gk*a>eAzFXyyyLu`0y*`w%#AJTS_n82n{4Pj z*tz#fPf)8y5m5jXv|nt}+c=$A3p>%*?`Cvj4s zN*g2W{Az|9f?9m7?3-D{aeIBNU9FR{kH}CLO;!5!<5xf z0gnoBqI;m0+0AfV6RI2SP;A)4CzDfc{a*6n)IV&l+$W#iYFQQd(iwi&LQ0Vcb(@h#7|py2iCh?q+X0l=PT40J&+$(9Vu)8gYuodmDF)L`T8z<`ktWsUW<3dZdf?+%I0Q=T@~8=tDP;no>tX`a+7&;nvD zrh%cQPKbQ4alpvg$6u5`Z@Ao_X`uSCO^k$g3&$%5ZL$aLy#>d)VbXIp}SNZM%KM0~8 z1vwqaJ|z!%d7;v;F?RjE6}4#>F?gCB?)T55BZ=mE1z#>-smr z%bj1AAVcYsX{>Wmv_aynN8K^sJ;ifz==kYuA@z1Rn)hZG0{w#-7!%o#bn(#SPv3gQ_5%u0 zd9X9(BwY+k?*gyYCdgzj=RV2LAH))}NSdkrbC? zDWW^w+-cf->t6z9{-F^QE8J3)mf+DXjAc7@-Q-9+%`hiAnt< z)EZNd@FV9_#r!Ya!Z^JxNc- z&@IeeIbbt1g*rarPM;UHeH1By^m<8rtaXYwi2lJnBQAus@hQ&$0H}Wd3#e2x){MD+ zDb=;|L%GlBz0+zB7f|Jxv6t0$8aQtV(4bU#G2p`e%1dkcV?J`+JQ4o5q%Gnl0bX5% z@W7i7Thyuv15FoZ0=QN$3U`H8*}6{7`F2fX)H)HAuaDi0VhmQC_u1Fff8P5X-mN9v z1<>c+kN_%b%vP@STb0N7hkm4*Q*fxS)0udPDlN>g|Egc z+3O~y8zz@OWNHD&DCH(S&h{40k8h}L70H6CXNBAs0l&_ki0t5Fw+Ld%Tf)pmJ3E*R zuiW~|?6))*Cl+&EZ>vnYm&bqx%tE`z*M@J*)NNXB(8E?$EKaZ1^fCp{#KlgWl;uUz zK~tCIjiu``j9+xT;y9wCC37$la;W5v4^18i%R-!x^RE{h)zGgWKY05sj=6%I2h9Sc z8?7SyO{sJrB;~lcU}jk7g7QX?xX_Lj>E4tGR;n~PF1zbBKi}&;d=J~e%-~y)w0EA) zkHq8YjL(QbVT``yI{XAVy%PTD7WW^~f5uneE!qnu#_*_S`K5?|G{Th&Eo{9uEKkGE zzFD5db+NzEJAMhCsp`=%Vy^q5&kj_fp+#}2h`b4_jSN~=duC&|2mws?Cp4AzLtdDD zjuHKeJx|H-fdWE|Ias-KbM@qzt61)Akg!n?1&-IEvf)vPeHf6{VDaN;0sy#Q>79}b zvi?o-3)~#CmPcgr{qIMvfBuQo-?foFVZ^PYRgLD|AqdEo?xjdosAXKoU+NeU_m&{< z>^<0^s^qUSUEX;gJn7T>O2^R0(t2|~VnpBkW3koX%3|r%IbpiuJ-3+KTOCqh+Vu{I zHu7)3D-?9dk7*ZVMgFvbtxrO1p%*)#0Y6d=tRo>F$RHmL+j>pdyDVK9aw{}>$^q;3 zjc(KrWFaZW&Xu0u8s%F#No%oViCF0OEDJ|U^IU8WqhQN@Z>*%-VV~~0KVDS~%}^6= zUw(A9iS`g)>g{>=$-@i5G4?`69Lv8a?lbXv6|o;2Wnc=IAkJ$}{Up32e4wjFhd;wX za`_5=wQ;;=|Gr#m=ItEgob{Y}XtK1=Ujk|eT6p}2gjq03-g_-(12on@Zc6^>c&;U# z410bl%QMo04IAJeK81X@k|Pn6QF5SsGSq~e0RqcpSyN^)j-RLoxLQfH49E5wY%~_^ z(lj}cXfN9KR0fB6jM?)Zap5WSUDxE@KdWT$V~FQ;ax?Mth}SrKQuhK;s0(pz$rO5v zJwN9E!R_=xKVeMbF9F7H-~J^1(+qC9#|JOwe9JXe}EWD*^2 zoq_1t8&|z~W=3#H8n^G&34}VZQsU_?pzhj9w$ar_{ecoSceiK(Z<7H!SlFanrB6Kh z_22XIG(M@Wm>Tz%cYiBMI^Q_yT^g$UW?$3~)bj1Wsuxbwxhg!U-QHrE`6?#0!bf`} zsBuXjR$63@JYb{ajcpl@k9N`~WKd2_b%(wtR^7Q_3H}o$W!A)lR0b&>Yn8r@r3Z)R z^EgYO$JUcClD-oddwpMTDtdkIs{vPT59gUA#id{S`chgjp^a;3I==;AkJlLNBAgs8 z4B0hiTNq?pQb08zeZd(W^NEK#NDb(nZH2kln&6Fm0S~hPJIhU=IO*#eHHT4ZRiN~8 z=Q33n8h4YxwT?*gf^}clz1O&AZ8SE8Me>fg|LrVjm>PQ)#Q)0Ui8KwKevHPwP0zW_2iBe$V-#{GA8W8s zL(+mqtA=R<$#a>g-|6rB7UdvE!>yvS%bh=h9X<0 zdfKuq?0?&5J%0cb@tJ{8_jC$%Gok%}G)MJ3x4H`d%JO1h0pQxg)TPqOA_V@pQM? z2ZFk@?@0vWL`$dgrd}|$zXe_6vjmkZ+SGFQS6nyLUHc9xk69eG${eI^Ya*fxRqiW3 zXO~f!h3}Qb^`@Meyv)u&ovk9NYCQbLHTq>*ft+Hpd)^v^Tj!o7bCOR%1X z*^A9N%Lz*ady_Ld0fDDh=`6$_+)|c~5*dXkc=Be$-6Z?6>29P3##VmWPO_B#Tu8sr zD7ycynC7A`3Y%eoK6OerTPbKGF51W#VwbrP#l7H0^%zrsJZ4eU=)sJm!u_B;+n7IU z+ct6McEiHX=Ihy~Ghxc}oBCHr)aHX=^XYc)PFgoBSS`6jnT7BD;3Y7vIJs z(ICEN3Y;~hx$=QJc5hG!o92@FXFQ0jCS{6*#tRF%OLudvZguKSrzY}ZvuVwEE;7xu zJ*oak7BU4j_iPBOG!?8Ven+%sK6{wm?76u3b?sS} zX_%67CG%f!U2yKT2GrA>S>KrHez*vFu6_Ue4XGu;gPV1vRAhr49*j%$OxJZn1{6^F zF%z=Xt?9+x+PmX1R&TEZe4-Vf;VwmNHHTQl z1Eqk2Yq$rYw+^rHO43fS*Kd6XTjhdNRVSX`0^@dKz{ihW6YDj*G_`i5E+;`X8QF(e z>86m#Ym&Npb{r)>Np)!Qki%MxX(06F1=+xYxtU!6*@5XR>;U&_oO#Gs+P4;XLmXU7 zOV6+tUm)}%@}YzqLL*SCG-(09n~UF^aVCm!FP$dK!47RleSQgAj2$n?H=X1`1E8VH zgCCV?lVq=1(iEl3Y6)_0RKTbhr4sOFUWP2s^n1kwz8$t2X^V~?R_plC=}{1KwlE9hAL}m@K39UKBoT%3{7R}0OL!+E zzPc)V@D74ZF^kqqHA|t4T?{{T-PO$>bCS#Ku%spWYLn~5AY=pMVtBp5J(zz3j78O&|lFNysbhIU=k%d{f7zeU6*%--n)y zn6JZzsw~_FQ3cdll7hIE>~dU2zKT)mTQ3oGRRY{e$QE<$SZ$4HOVP4!?^vJ;{iVW* z6itQEcpE9FDDBqhw7KLrf4-b}vHYM!v#j;R!=&5}1GO+gs!rcjcC69hPXeJX)}bys zH^$v(y`plS*eN0rP_~gsd@cuUNvuph(O7-jhoj@DnItIIXE`oPI82JnvT@U)`MKn| z-@K*Fn+?$xoSJ?K#*bSd2wY75bSkj~bpFi#oAtv5dp=}Px&5<3c~+n0Agq4GCU$+M zAj|cUMl%GZ&4W~6`ZYOI8L@7Zbn;Gj>xRU)HGQnGUULYDMb~Myp3FEq{Ti*v|Eqy` z|8D9UysI$Boc3F{^uZ)f(FPC_e_|F7XUY5~t`?}y6Q-1#xgDjRkdKyKBqGeR$r_bc zP4y%YIr(LAeYSTkQe*d3Yv{NqMrh;RW4zh>4{KwmezdDheIs5J)x=@+3URwbJ{@-p z(ptO;hYE^D@6mLVr?j!QD=cxJ&RSz-I%=!H2w*31k$0|#M3q>z-3^s|ZnNmn*&9yt z0a?|p`5;ruZr6-+$&);`*4-LQz8Myh!qbO9%)ECQjTH_p3_NK0`(zG-andZsDDMnQ zW8B6VdV4CA@CW!zE-D}Rop(WDMzCGLmj^8;ui@B!(cKnjz@9H021eVu_LJM_lb8u@ z@GhEvmbCN|i7&p7g57+0d6KWLtyGhd99@Q;%J|rOq}CK|K`Y%9u+bM!58WmG`IYiS z#BSFd+^AkPWVTsmWI;^4$1B(4!-X`?%hf7|4lU}7LO`cvZ`ZhfDuKK7hSu=h}j}?J?ncda0Mte3a?A84Q zZz?^lLsIY6QD#dk-8Ff-xok6~jma9ThF!St=D4NI{9JmOLA;9fHCw3buGd!P)>pOC z_oWqLU8A&w*z>|{L<@Mha)iA|4&tdznEzJwgVedG4EnQQZ$tb+Z^u@WVa7zzE4_!r zqD^OlA_UbtINi^l4A`$6e%PWTn1_r-k(}a*l^yyEiL&A2b4PGnigNoa=fE=G-)RU- z86Lb&bqnLrBLU!q8Kf4p*u4-971zk85 z(Lr>y_bXtUS(XMf1cY=pA^c>a*$Q}Hh7uTOYhLf*6-c}+Hl&voQf?IM1`RT;#sp-L ze!sB=nK+bLecngrLjb+YO=qVc4GZ+H4LQz!VhARgQP)HrRRm^+*T+;ecc`SQ0JQd% zE=ZMY-=<5qa=L9XelbQDdqOee>?78ZO~ZTe*;p1tRVb8qIr5%hpXY%B@H;4RLQTGc zfyq4H179rQ4HOmH;a;qbsl$VFutTQS6MQXpNnim7#`p2{%o6qagbpozW??OtJ+M=< z!YuWqA3)aJuadgf`WcghJ1yHUS0~+^`|{9rL{2z=PkYA95edpZCds`AQ3@Ul4q-Dl zY2;@q^rKnw2?vrTCqXq)k!oG;$2LLEX^0|V>q}&%#(Bupt$0Pm#S6tph!gV5d9qcX zqih*#NhwPPojHaR-GNGw}jamdb( z#Svoc_$=@1rL;elkIc@A9Q9|O640JvT?rWK|MG*={U(>T0WgyMt9inir3B#7U@NnE zqrkrSki2POB5tLurw#5d6S_1jK~B?p))i6F2Z`ZUp#Xn;N@BmmkZ3P{so;1`0_SW` zS1zFjJFC!$7{$8Dgw-07pn)pA;x)6JqU?Nc#m$X4<$M8SjIGiw+}4$AS4=P=*2Tr9 zsB@KIu}Dw?Vz86Mog){j0HH16n;Ec)eUDG{z#^nHO=_o$xQ9WNgajJMaY@Z(_@$n6 zM>s`9)_SIL=P))62gtd`(4=H#AnMTg`)*c#>k2z&c>I}*6lXPbPlT9Ds=|iM}k{YB#wlr+J&L30<({mKK zJMxqeo~A9CovmkycvBVxCk;+YSH?et-%tIde~%N52&U5&AVqx<%y?p$dbjM@^d_Uz zVr$`r0yJh}tIy_tzeEid8x3?T9L^pJyZJ2N`3);1^ztm5ifpXG?@Wp|fym`BbD`HE z7qhGe*#z#WGC%)11%xtu$+^yeW@bWqecztvBQN z5Dyi#2m5*KLFn)B-Jfk3GCyB^8LZ4Lk&}t*r{mBf$3TpW3Yb)raV}X7svmp~=$U;; z+7HsiGOC^ViyKPaP_8}E z{4KYyll4yH{%3+%sIY@ZpPOnF!iI|f3i+GMDqB%tmRX~~B~I*uTa=`rI(jeDW7*65 z;_xpxgaJMg-7nl&K&8pIg@|ALW@xaV{ujNOVs)1|r4`bWTG*%1vdI+#Wot1J#0hu^ zdXq1u% z#W^S;42fYGbs8`yF{$Q9hcDuBok)t;=*;dJlX)uuW3NJmQ_dQVKNlAy=ue`;j^~6o z2cN6+k!0ypdTh+|4{6HHanE>q{CUxrUZ|aOEBlL?g3EU9eZe?P@bUK#iiDq{ghMM3 zQ8eGh{cW6W5Pov1J5qPa9HInjpg~3wIl5%wJ3~sElO| zWltHgDKt~KN(R4E&qFv#_}hLjxiy5O(~{1$<%`;CUbL%IXo>p%Ong6M$GV-{gR#@y zpPul9_W4~kLp!k!wJ^#&!x;3LDxCG3`3>cIBl8;c4G$bjY~?32h1Ues# zrlirOILAOcgbRgT4FA^E$Yf4t)-wCh@jf&7fzRnNR~|}OsL`6Q&@N_jOZ`jKB(pbZ z3?4#fOvEV)H9`Cd*reTB_v$rji0%gtoJr=!_{%GqQ32Jqm(IPl8Sr_n=GU1n7rDv& z?wZ<~nMlgW1EDirjNni)jOv*ol@x|4!8?~-#znXyf^n)V@Jy)WeaLF`cqqcAm%OiA zm=Lu%SYy-~yai<=4Pb?JYuyo`U;j@=hM1I=F(H59^EE1PXI5>bZ&}yK_WR68@r{*+ z_-mrkSq?0jVgmFPx75*_%`4cCQrHjv{I1p-XOCEHx#5*gI$-i3mSp@$hpY(r7XB~}2eBF7&gu4+`kV)&l~BZ54C#IF4im9$ zMY2+9=70;(D-joD$bQQI8cV4q>FoO)+;EJ-p>Ur*-jLdEsCl7MFh2aSfAtKs^Zq9L zhn6JoGHt$*99m^ahZ{fC#&pQ;>f2u-RI+%@Ql_B0DYkEH;?gs+ZuJ0oc-l!N7(`U` z_CdYdY^qJ^$cC>6)irXouf!m)1j#4Q()d6Oc&=`grN=&$ zi22**NhByIj;HDb7G#nFhY3iS+Ib|L$l!^)LuJOTlAwJwdCPq*gXJd$_C%_tq zWM%y`{}2PR`D%IV%DhAnlEFN4H1) zwj$Eplk!Lb(eFA!0@d$li7#?vaAW#i@@?m6%!V2*d&C!8@mwgHr8qC-z5lgzyS=?^ zS^k&d$X?4xD)+OhM&ycNik_(A9t~l-T>Z7}=Mt-FG5h?ny^C8P-+3n26THF$TD4j* zHjN34ZV*`G3P?(RKZL#Ny>cdf9-M=wn@BTvBE8;9IDglou9vp^lOog1i>p9=KW*-u zRi|N@rISv51v8kP)wtse#_2P@l2U4B~vl_*04c#(KodEUKEp%|7IHAZcM)EO3?b zdE7q9rX2y-TK5$1L)@kQ_RHs7k6tRixHTrZOyaF1*D(?vT0rm-%nH%U5}&=E3f6D{ z(@e-*=_hg;cbAyvyKYS_at}jaSs$OnhK#wsCoUBe&QIrOD=)WIOT8yTUe_HIP&<&^ z5uf@JGgmi%&r@&H8843Grs&*b2wMdPp5|OP!uYdImX7omhSvMjcI{wimg@%DH}-_Z zq8l>(zK%X5_wOw#ElE%Z+DWsjr#58~ZAg{ij!NmNj)aA$vra}6aF6VCw8G&K^fewA zqHBui!E&t3`!+oR*}ySQRhPsCk3La9e4VqgJuC%_O9ze5RdP;f$>j(djywXl)OIjC zB^vxa+M?K{kKK;e$*uK87i4~tv*eX_eIwz~5wTIGU*pas5`O~xPJH&J@Ybuqa5TKh zh`>}ROakn|HFP>G#*s)RzYHwi?4Zr`i#$1&QQuAoeh_f5lFg9H{)J+q-dWN?IwRz*vMtk4EuUj*rb_ry zJyv{Ytxr3vjhK^%3%IY$^~QfPQ?mu!J1ugBi9NX|no~Gz-7GRsfuBXIfjy<~LwI|G1e&(^lqv5PwY{Z=zb3y|~wf z%0#$$b;?wWlDoW}=K|p?JA#~$6^h44kh!1QS1mYqZ+{~$Pg$CO^Wj>vhHenHWhZ|u zI>rv&GAZCJP(U=&U168miznC(_ky%)=joo#zs3&CyWH7B=QX zU|}5INJo@-{rBC0sa&SeFOrs39g z`yJ2WR=7!@1i(XqNhXkyZ&}I94KmoXQRkKO7M<;$y|qZcR*dd+(P(8 zU0-M^HtI=a&oK`A?nl#Sspe+;czP9mtejEV?Jc~dL1{QJ9ghf0luYtid31+2QJ-qS zE-owSMH&5hi z{yM29_fc=)SO_+Pl=gil6rjN=MV+*Au{LfV7bb3+vlnMU4Ii(j-B0`bQ}@+y`?}N; z_|>=qEFyS*ZQ18QX+>zKJ^W9)?sNbmA;VU=G?9?cWas|XqO@pBL-}yIa*|Kxm-gyZ zSVo%9^~4q<-`tmXlY0h61b_?tT!>V?aWPA@T?=&shs6tx@SbecXuooNf;D6&{o3?m z&MbxkqZpcglu2j#kq^^Hl1}AV5W+rVO<}S__23Vo?%y_eVc*O#lTm7~o}^ISElZcO zod6r056tVaL5$|bY^5(^p*V86M5qtZC6e-P`+h6Y6a;wiR(23EDqa&n8DrD(L2vPm zdfLfea(tC6X^hQ$MZS!&M{Zhob%n2`gt&8jJ%L}iUyTZ2+@jZQSFP9nktM{QghZOpQ z^*MWd5K=Ca*}1~USR38237oht^I4WYIW1cND?eW^C;W=7-nL5`X6G`n_7Pnke##^O zD*v#fpV4ynlmmi^DbHdZ6jlfPtrz1LmVny#Q#`CqqL&YA;7{ztmqbfOCvJ+dwZ4-F-Bx{GjEU z)sUq4M$RDY@cQ|#r6#gvLkJcVmt)oUTu7^f5^Z~SD=`(H^e6$Bx{H~? zg+NVtaI*Zc$@&{P*76g^1I(^-a6{piA0Xr|uxe`}Gg@azEm^va)%QzE^$nXsYfl01 zQjh7pFLnBdtymAQT;rZo_X`80i^Wc~*jq%}$G&oK2_0kci~O=3L)wd4>p;EcPy7(_ z2li;ac*I7)PLk^c8{Gd!5vFtyG>`ZvV+r}C7&O)Q zHdJDoaMVoyLa=w%>O@}~N|b(hF*|i}dmJ-gen2VOhIk)8tmDVn84**~q-C7+u`YuL zp%+1qHaq6YcL(-(NImTVo&xD!<1Ap#aY>hYE6`wnd}?}QNDE(8PM0~e96nbdlv%0jG?`I zt=<%^V|OzgDbw}dklXP5%nALFeGn*<1;JMZH}3p}w``vXfc!$*WYsI#)k_dZeOY@jxt0-14yWcF89Uu93V#;ndMyKlE z$8Tru#>6X+p#TgA{d>Ip6SF}LtXRzvo#&GtD);-uipl5S2qAnUHqlvl#)bxoE8d1A zhEcqlL2(J7UzX3k5Q5v&I>sWe0$bt~xvFPk;Rrw36{)8bBbrd(Yb#?`xQzg!va3Z; zOD&H58bU@9nQ(8crh;7=l{!CEGcd2h@KKHlhzTZ>%vRW1VgeJ$G_U(nf9Lv9c%&;DkkG1|X z19^-joJ)pvCD1Ju?8~&o&8;{>vKL?3w0lvg_g+dXuD^ZySNOLg8IXqqEFZEP4Rois zwUAeaR20ik-G7TlPOwrQ+x|(hE;fntrLOGbXcjmjUx&sa-n$imFi1+3s$)*NqZk~N zh`F?C_SeU)xQB5o4JuM*9aHwh#N~1zyUhxO@|k+MrkMv3u&v+ETpZ*My%r~_>mvSB z@)i%zSN-~E`Ql@D2>8kj_K>Imj)NFiEyvtohpICIm7x9Ex!xkN*eW;Tq!Vuv4_x!Q zBD;jOF#F%)uHE2U(o>yiuT`CJZIxpUSTmWCh++J6!Go6U!EQs+ZAj6o`&^)@e3uYz{*0qHyVepcRrY2I1? zXbglnz4vQB0N36a_oGnPvaTzuHD6I0(BzK_y9o(aw^j+5sj3od{Ej?#+vzBTH0B$& znAD6@0I3GT2r|NKQ<@6j$pO%>$p+57R!HpA&IdPw7XiVd^ z8prr?v;1mUs>if}HB5t1EKMxiNyo^`VxD1mFEQdP3GSD}CtW{s{fJ<1fb<14(Di?5 zwi)TY{!r~M-h0rgWsfUDYB`){ zrHnL&Hh}G}Ltjr=8C`PYnD#(Om}3$KB>UvemP_whS>wF!j5FccV7^^cdDc+r?tb%$ z#z^w;mNRTy^~N4{8()XQdG^MUq{-9HsH8EaGc>i5s4!CFEOFr2s-|@2B;~S{W7sX2 z>>&lBzqNvi7e>{tuC|%Kp9V4FO?{B;=`M%99So~2BEMHm6KS|d# z?B~hS!q=pqw-ovB5le3U@!$`gg$!yE(%Cs9e4*|hkZItoAV@51cvi9L?mXCHM$d|Z z{R3SKGMR36e9E8~jbE)`Hd(>%W(`yV_2Uvw2pWmgt|95rp4*EF%fcpCux zeAUYj=T@577qmrRfyY5+JiYQ{l_}*EH9J09nOSY>E(QhA4j(vW<8v(#kl<=QWJL6% z$$SaS_fIV7gL& zUi_u%m@x!?luFosf?cDTi5i|0m8&s=3D1b(4cBYRx@8g(U~@kBeQ(3wxl@PlK+sVS z>KBQg2Z}rbZs32UPYTbBtHZ(6HJ&}d$^c|N$GSPB~G~gMQWz{F=yCZ$+@yKW}lH~XQZ3i zhULIVa*Z?B86TtI{yI08{PIVPaMAo^y9-f3;)w6#zWcu=JI4(6B-Yc1Hz|tY76_NM zqMC^46-GDXc^@bA`k-tHWpHQjMnJ~bd39s^2*K<_`ibL=-k+*kMHS|Y(C$nHc{bC{ z78doA*;zXU?S;t5^uNtLgv>g zV)4dc*FP2e0cz6ZhMl@tA`* zZ|~iD)1_m)Ir#cpw`MEhC(cA!&J!LgC|vZ_ZhH!l1NCj%K`cVrXqVQy-OHzFYuoqq z2xABOX3z)QCLdWb_M&^Ydp`O^Jm+0NN|z2T0&Ef%K=ma}y~f}MJmBKcmHsPp){%X+ zVr+qWCiO8^>K3;FF)5&6fo`Z3z^jJuN4B^|rFU zik(hrh@>u*~2V#oX< zoytp8-|tm)qeUyFn^cmfxSmjHTjk?m*-1PIHP)hfja0?=+TRi`1O{Yy(ogY3W7c`U zLXK7lvlOUBNvssqKgM!9lPwlpYK0y$l=#G4F~hx!6ny1XuE-zbwFjp^lg^*=B-B3l z9Rjy0sPWMRvVV&fq^%%>RRo9_47%G^vJM zU3k?{DiX0P3ovE3)s$Uw4mN1&^x$COhd&6AK$^L)=w7NuGFn^DrZMDid-#z@)r>#` zDCB}B;E%(Xz4}>glh5s(8xV~zdrJ=?lX-=&5tl=dleX)(7m(LQ3{4szHctHJd;q_= z2G*M0_{xRfl~fc3m+FzDcLQAcuozvjk;lLm0U1$P+Hj*3MEXWuu7-;x#%ai&OhM!P z1z^)B4e3!*@&!QPI49os`d`Kvt7PVC7Ys=S5#%Ca&M+hRH&Us=aXR3LdQ0+EQb&e2-<7aPeKGb zk$S2#s_-QOVdJ*+peJ6x ze7L*zSf(m*gDWfrV*M;vatKw;s?THe$BDV~76pJezgz`9o)xH-?$v}Upbw;YsCrAH zfrFz7e2(QtoTr)-j55Td8eT&OGV_gt8ehE9EkKlE2ti-aw?x+B><*)t9zG);z*<;3 zd)$!45Vj}Xsr^?skrT}Pty1)q&=xIgDvc$JM47zUS;0us`f)>1x>{)GGU;gS?_6+e zjv;r3c#ag|gJceQR@=F&=uarQw&2j&{wV+NV@jqbvAzSNjeX#>MVCJdi3Het-6_o= z&~-LgyhFl`?4K3p5!s(cuVmnacXsF+BklPzoln-q9L<9oeY(F5Qx*@u#zNYdE#Zw@ zfD~7}i)$>YZtMYGoJe_~aKU)KpvwKotLAz=U)*hP8%{904@Vx~8I<7V87DVN4IO*WR&f*wN zEydnm`+f4T!>Cv85!-)o?%L~le1}d$$Z%N{ACe2CSS^IAef63hr7rZj?%x>`TdAb6 zD5m3_8_g5oC^;Ca+R}@`LQF>B0GYtxLu7>ILF{zj)5&tDRi&{mwrCzopJJbQkBOM4 zeMmV-n%+x&NXAOr4JSD(yQ-D@wo)HR^SvOvRMgp5Yl8Jjv5?z{vsS*1dfL}xt2O&h zVz^CVgvo)OZH53EF4le`!<@CkYp|;b#Kyu86~Ft={*gybm{t{-QQ||d6-w35OlKbg zhG4PVk9C z-YKyrRvW)VgNQRpKFfzj`kKXQZJ|}xvgbH`87g4YUJ|_H{-lAX!VN16K%tly0dX&v>iu5lzAKit76~RH@-iTb z+wqbve@x9(TtWa^^WGUaFNY>m?1wckDWVBiNQ(}*(XFvsseL5LLnM4J(cVnSw8o!n zi@+E}2S4W8GCZ~By`#=veDh>(>@g?=X_O^PVN;ppF?Ie@BJND|?yuk6^-(yL{Q{_} zA_`T?cNga;!Hg?Fto3O&vunHMkp7|3ir??bo&gL`&ivLIE#w*6cyF#T+JCBG4FCHi zcE*Q0QQCo7rQg@S0^&`pme=^Iy4CO1`UXK`zIB?p)x?KThEjppMcVeLcy1D^oX*bP z(~!?bnsL!yaWagv!-+5Ypcx8JFDCm4E_bh4l1R0G-ap^Dqp3ht*d*M7uL-byOHc_H z={(I9ZJH8P4S8)gZB)H?k5SZtIIJwcllf9gIJg890l$iI*R2iU?zu)}$^3h*(iq>L znNO}U1ky`AvH7z+QawTf2o%E8;dMMQC>+XnEs$RAmz0hRQU7S6MA8|zE!rUE!&O~O zd3zS*zQ}Q|MHy#7M~3J0l(?uwR7r9Fi5(=!_bsyo+&LdSZzORpFfdxbKuHMop1o=8 zI4w7dba}BOoP9D{wZC4voUaVGoG&S@*kSXF({_vK>rgM0?zAdRetMKGeW*LcE=5(b zdOAQ~vkvg$P0^v@g;qx&;$YPWiYxwII0Tje8B{K8haJAKuj=HrSOKu$zdIX0gT-rp ziLsky63ckKJ8-?xnEMh_Xr3=U`@)AA`*<=V+p*v|UnWd){QEnQTv$KJ2QT{NvN&}a zIJe4%9@gB~NtG42ZM+UK7l8^MI9e95sStTQIpw5UEQ{o7($Lk?O0JFlV*j~4^wd|e zvrB0mtRH*9WTz2hE|OyIprlW5|7eaQ;g-zaLinm18>>F@pMfr#Nkg5aa<+>TYdiFM z#C352@Es+hj?1Cx`qp4Uy22ng&~Pj_1C^rO9}f&SmfU%6QjmG7=x<=(Y_TSCzQ{#_ zb=wq2eF;=4P+?cOBT9Btr12vH|LRzGKe3WZw^Hvro#jqs?-z3OV1lxr3V%awMz@}H zH0Z{iXaUZS*btRYi%GN@ch8)cde1)f&%$<9s-vnZW35=?uIw0)aD(`ZTBk^v)zRq( z&wGj-tNO|OkSq=3`>675OZ8pmIY@QTui`H?+^yW<^pAB>=W|{6IoJM$Irj3Gss)ob zObwhTF5;vNdkGU4T+NPAq@!WhfzT+;Y7xzC2jjVkHS{z}C#kQr&59bARiF)P^M%>; zd@gA1E8%L8=lpv6&%%7Z(mFWEvVTxJ$?Nql>iT(idujyaNA8NdW z6SQKnqhHDz<6Yw7=j=NPxPPCgkoL&VPekIP(u!K<*h7=a{RCPK{rB4+VZ2_c*NQBE z3%ZyT+DgQOYpcpmr$2-X=ac5u?5vz+ENwkWjw*29bA@`0Jg|Rq%_zSCBW)+{l#KCT zgHJK(7h{*{3$gxkQL-dKJ9=QGGpR5*2_alRE5iFg&H9dKH7xE6+BMG+oK>WOi|YBp zBj~jlt)`q^cR<(*!E~BZfI3k`a@Hi^d|kMH^uF%LS$88QF1#4jPIkQ=vwvE3hA1P5 z_H$9bcib)kV&mur*jAi}MADlLh1^z;5=*+yi0WI$WxaI}QGFfrv)%StfD~Bvwpi#x zZO7>Sb5cD~YtjnG5OsREI?A*+LXIqK&zd<-$u-8hIzIeVokM`P(qdkj7$$S_3qJLRVS4vb84^)_OZIj7%aCkeib6Q8a&v8GhB;I8XU9^-|_%;$d z8)pttK^2KrCVi8XcS&r*?g8_Z5$jHm4#RQaztHEtRRv?7fZ3=8%!bwGOt=QdEOcj$ z7CA1qMC}l_kQJHzyC5J-Ey&A;2J%@DDt;UrQ*%ES;FT}yKv{^2$%U()B)o(K6s3}G zefR;>-0_%F{z==ws$sfkdhg6hAt})^lv`qmJ>e&wna!f!UhTBZIwztCx;Q4qus-{I z_OkA!O5WZ2U|F)^Beo?-QC?=@zJETVl^nRk$-a0NzaLWAyHbg+JaBQ~`el^_b8ZNy z!p1U~#(@ftn_a4!Qag}nD*8NxU)YJHo~Gt5Cu~+&mR(^q8kBaHx1x5HQJ2nDb7dzR zDAMar=^fV+4s6yqrX25TDPu}llb_=C+J3;-9#dWr4bUEE0B!O4w#?~0J_sn618`KZ+&Wz0mp*OZRofgp#cE{25H*=Yct)T% z@#pA5HbbGXoi}h#lIO0viAkGgZ8e1+vFyJZOtYmn2>i5TGhPSM8 zH~-C!(bSb-37nQnh4zCOzlKS>ogCx2dY3sNuQMl<2cF_^r7tv4RN4 zn=hf(ANt-b*9Y{N6^jS^H@Rp&a2$l{7aOGG8mJvrGiKLdqHRCT`WK;`-qtPa&O6TX zg9!pqF7pKa`uEzp7Y^hY zyOz)Gp|Km_kSWUdchkE%8Ey9Tw!cGhoPd{ zIt6)(bq~zG#gE9xGqV>|vUIO@)cEpyaL3GOtJb5_mUW-qi#`xp|LQ*7M4|}@bx?=i zVj|5*Ig>R%A4C6C$a`NRf4#d8e!=5#aL<28Px#0hj&tBw5NU*4NuP_}^ljQ9zDeH{ z)Jlok>2lIpe7#doUR#K|XcvS3pv!?zgv5M4BGw zDt7eO0z;|sD)(A`y51~Dr}d*aKj-wCBI&h6M>ediV64SWz|DCGYI!CvkYp1Py4eB`1s!^9&@QyJXC`6an#lM>`30~R;A{WluxxtH z_VT1l%)f|YZIw`L=*)un@!4?pe-+2Pa z=k_semOUt>7`uc#`TTC!ZRQP3YwQ~W$X}Gp%gsl-*Nae=s^7%}<(S$}_Tak`gZao@ z1)jr&$K*Htq}8)eetBt8#^>OM{%H^n8V(}P6rKO^sEOz~;G&dw727d(3^Z;;7fwQ& zn6t{!VjLFwJ^#OFoVcs<>N(tcfU}l<{$WgF)p` zxlV}RqfRj>^rQO~_EZFIsBd*3>x4^$!-V$YSt7uxImbF4tx1A& zw6=$OV*(8an(KL;aE4{+CfH5qb9a>lvpOB+Ns(CD-njiUe&HqiLGx`9dB|YdnH;d? z>4aZJ(!*hj$^3H#`aj4{tTUFzs66|(!S8$}y3;X)qgS3gk(#~!pxlLXrbGeks{YeW zj9H!3q)r?|dv*+-S9$qI9}(a2@J}}j7D9IG?A>05u6E$njorl_WU(=MUt=iwdhj^k5u5wEpnMfTJv?e^xacHwEk=9GX`q+s6TfJi6 zx@W6wTO(F05>@Yd?Z)f_N^XSGqh_s`j@&+}}b49jIPPUF1*UWn7LT%wgh?P#+k?JRg$W`tBI6mweCXU^Cym9a(dDx4kssUe4QHnchP;}NbM!cNt zc!BpO5It~}0-ryCR&vFfGnKgV?}NLgBz>0n{LP{~*gVH3{>WzxZqp_v1glZm8)mHg?jH)O{!Zo&tsgLl+**JwW;-*#<&)O&xL^a~lGL=;+>t1S z<|bntRhpO3iFf!qXUO7YH+Aro+x!ToeD9XO8VQwg65Kgvm+{AoBa1WISImNLx?Qt2cQkB7g#&ws~ZLl-F7wqy#y$q~>>G z&$ayEAJplbgD*;sVx4j^toTT{1h@;E#)E~#1h)jVj$~FUy$FNvu)w#BjN_h)nU$-x zGI9soQuK3;3znRM*KlG}er$XPs#^lt%Y_Y7D4Ig}f=_<;+c)@c-){p;@itUQgan99 zshx}Q6@a$!OPDK2VtA2#&&EKPMPGh97NJnquJ~2^o%)$M9=&ZBr=Au+Clg=NR@f{6K+l0+uoEM7Q$9-3gcV;H0TlBKygyrV&r-VVzbJ29Tpef0rfd9JpRK2s z-@j+tY9i;hT+)2{5%wD@L$nxkcU;M?=}mV6!0K5N_=l<_0s++X>;#Y`y$_4H<^Qk0 zt88$?bP3MR$N$&I1RI8p6Y}mQMQ6U@PYUiquc7r!A}beL5S4OIq3i{!XJQ#rCD zePTd8?u9o*gnmoNX7937-1P9d`Zt$h_X@~}(maSUg}!8M}yCE5A@!lL}I~+uUN2I?xbeXC*U{G(+#S!i*$?(dNte>r+F|5y?^Hu!404E=z zo&apxv~)|1bkA%aafW=ajBiVIU%|G~1G_Bb?Q19AXv2YJj#FJN4;}+NwX^`>`iHL^ z5(vby^*l+{xb6N1ecQEoN~6EPHmqmG;TKFk>o*6BdiZfxrPoKL1&!Dnsg**n`-GPh zLT@-+e~8-)JbA@i$^1j>&9EOlfE*b|EkdI2Cu_iM*pC(3zyJuKT6ZZxwSP|rumzLh zBbk0A)90WHg*szv2_sYBmpITj{rdM2&kZUG3g6h=D9>}!Ny7ZCVGw-;mq4y4Xqc%jy#!2ba(2~msy literal 0 HcmV?d00001 diff --git a/dependency-check-gradle/images/profiles/sandbox.png b/dependency-check-gradle/images/profiles/sandbox.png new file mode 100644 index 0000000000000000000000000000000000000000..f88b3626761f591fefcb7408ff290b4f48ebe0d9 GIT binary patch literal 33010 zcmeFYV|Qd-)GnMW3YKVhRGV(B%(Nk3lpLv9v_0*x9}+hfP}^Cd6M z@qvE+vy;v|7Bec=cQvJ<{@Gr8|Qo^Y7^2zXs9canPLPgB~+OYO(p7)9@x8bXMLl$NO=7mV~-#f`-BW|yF^-Z9JRRii#Yv7Cn-Vb)LqAyu2vZrW|`^Q zbQn~Gl%2-vAa+};BSfgE%%k~>f6B?Vc^o|)?Amwx7s_eSXRJf_4|0%-1#?k3f8d?$9;P)pH@ z%0*MqNqaqJCP9FkQAv^gE_d5u7J*$QB2eWc`mjz~-)vkdSY_Fb>nKqz{ml(=nl1H` z${j-sslDo2|LLnOf>Ibxe|pct=+ss<`kz222Eoc)waMXgsyX?&Gt<_d=zGy&+~-7A zF`b-lN`>rb-rF^0L>gF+;IpGWJ?3S&+>VJKyDx3PY9?oj_g&4e{562|jfE!GvJI|E5KvThis^SS zDOc#Bh`x~^#;Al!W6eY*dIX1GNc!nWGBwhxOtt(87f{V=OFxdR3|x5czB--|ybqi) zaes%^$LpPSVZzC0cRPTu_0?xM!(Jy5$ZZKs;$JtZ{$^*?9wVqxx$erOOAOh8TDh1v z{d;lq_#gn$v*-=Bf&yWwzrcVEtT6D7(%LQ%5Qv!nU62r&*|-o8q!2RVBI=%y=YDX8 zRGMxNDp!?Tf2=*a^gZ^2=|HWID9vP$u?jTM0BGr3I2KAWNO>7r_?5&NJKKE(rj^#m z;6L6mEfqE1SBIb7>@HG8Wi-|9nmXUCra9@mxLuBaUPaw?xm?mYVOknbqOm|DL5lUF zX_-Rr;duFHZT;UH%FwZi=cs-EXGuzp#v&RWmC*Oa2#5;^4qbZ#xRgSAzfDHWD7Zjq#pIt;GL%42Vm%y8VA13m29rH4MeVBne^c|6iiO zu@Bh)c^ejJV*n&YamEv_E&Bgbk(7Sm{*M}XiG~T@W@vE4Fy?=$u!z?8{C5cOGAKj1 z7f44f2&)_VKQ9*^h@Sk8{J+Epp#hT8tT(JHEfe#4pH74DOq!kw}+T3J|4Y-k!NzTrqzZn~gsbkA>i3f}LBs%SxIauWD zVtNM$c^Y#)7sH2NUQ2BDB~LteCGg5Cl4j#kqLgHk20I1D_$+gw3{H2U${g`gV^+@ zzNXMuaFl}IeqgY(6`zWcqy}^MXw!a7_~P&fAWBNt-D$7Lf>p`@%wIs1jZhfAeqY2`@WF0N5aX{~ICl*Al@xT^k4tor;!xeJS3}^(j6~cpS&&AjMFB39>2q8_Q04TsuHX zM{hGO>i+i7GKaJmJ@8BQ1rlzweflkjvbeP08%`{VmruUWnsp18j1l&fs|>9D=jZ?< zyHblkUn<@YYl#BNkfmBy0xx^NLwf|?$E*ygLm z)Iw41$1rATYn7xVRgRg5T~3N(KVY+h8CXzUqC?f4GiL@yBJyq5wCn10QV5 zmt6mLbv@St^B)i{e`}|-jX*B7d2%%BxA7j*B*s7g9w-OQPbRDUU_8ObmXz&)Iudx` zM7ARCYb^Lr7E#fGRuUZ3O#;uw92re=;vyyp^YuTwY&fHWgW;f8H(!e zutw>|z0J@ieKGJeI#o!*B9~0Uk;M@bl&jGQaW5`*BZG}&K-s1BXD6OWHQ@E4{%FmH zaXQDJ{Pi;8*ZBj{5?2aY?KTA(S4-T(gDeF=P4}`(N%9Q?9m$cg=UP-|Y+AEQV6PA{ z*hNeW7f2-1EbtL(`?-sHk7Tt-BM4gi)zQMjzFuwwEiZ;pWK@F;W{44*av6;I(nDjm zdp0`f+XvUl_FMQ=y4Q7|Dl9V9<0!>_7Y2_0MHJj-u5ItHON4FkKYVW_6#Ca7<~O6E zP*aP~ZCxB!FqI#7@F$F_9e z?&KK}`&0&W7B(za|KxIPKCce^Vd@n2P9&)bxHGrvyz;N`K0Y)Y4qKdgaK8U@j0x#c%U+g4$#O#z?0V}k!?hRDXXaXQ}YGs7F-1l87)$ZG!rdF(`7ybs17u1LqpCA8?HC$g-mKpX!)SgQUkRx^%~!(QeNgv;X3F{*$b>hXO4TF;H34e&Oq>-w88mDXR<} zbBd~|4z1^zE|nl1yfYp?I%LR+eH*8gY;5K4wp~f8g6PK{C0UierA=LXAN|<(jPOR> z^7ZU+;aG~DP==<$*<50)rvZ|Z!=P8Q#!6i|(SyFUj+l_76Mp}QnevR1| zpf}$j2T=tJXGDgt?~ePS);oWmh~SYBriM<)kMW;~8yQ+U+k-A?H-tKeet{xh85WoA z9TZRnX`47U3##8{;7Wi~gz>dMPq&PXHo@%eFEg}Zf&PLC>D! zqLd6J_#~o`Ca#(gK1xX2QPwp{`Mec&h_=8{QE+& zs2fbZb2u*@ZTCL}~|!8Aeg;jD~H@K{comA5 z9{GIaZy8hOZM1YLXm#^<6^bq&N7`t{*adMlzK0W-7FWt)B-KG;{_R0OXe~NnMq!ox zGaGw|)l=Uvm1>XXEhKAy-udZYtf0fqA9RH<^ZwM0KIi|oyT0^D0^NTw_q^s^(erG6 zA|?aVyb$e7C$g4DzVMaY=mZZQH2oX*<(i(F!ze*ol1ap042L(}vAq)fRNRzeK4sSW7`B#-J|{|MvyTs84GiQDq-ncG z>%Q4~EyjLc8HR)9IM(a?WzlQ3Yb!GqVjgnzGHrK~JDk>BKkno1JK+kx>JF?N zuIIJuKdbfiPflIAjpvii)C8#~U-|oWVaz#md}sPcV-eao16+Ul4~{@gO33u$WY|p$ zF(dQP?cvk@qDUm>2zsYJXfzVE(T97~52(G$y*LKGh z9NI%;k!m#1QT9^m>s{kyNn=IU28NyXek7{|AX%H5Nb_>QD%iGhM|ixPF3O4zT-dRp zkSi+7*S;Pe&(|4}RG`lVi`YOB0A6u}gz1enF43*R8$>8n*O4gbxqGTDi0-NBMzqoY zP}jD(lvwGY=aBT<;pnJg1RI=abF*?CwFTU13k=*utgj`G8=84G9zL$MNDb4_RN5s+ zS)?WY+*ZW#m6DW3M5$9S1TqK!AlnRo>qA>FZ8}%BJKF@(|88cZ_qgF#OnN%N0xBdp z7V#h^hy)%0g377c4zg{62l}TvE{C5L(g$}5X^x*-d07l-qw0I3f0wl|T}jDr>iQ>Z_{0WY8|jEP4~UEizZfXF4*BHqLRLHiNafW1HLCwFC# z>k^J;b&ZJq4!^tYje3Ej>#I=;w?B#@diJjdqwiqsNZHQSOvaK2Y;`#N?I$n2?lLU{ zbvuo0yZXC0vF=isuIsPpSOnKVX>riD;_GZok`Rme2z`w-(cH(s9S^`%7KWjFQ3zm+ z8uD1|tqar2i7(Gb|0~Ed9jj;oFqXJ~M{Gbt!IL@|ikLmyfpWKK>5%~Y=kyoCt4-dh z1Vhr}$4k_)r9oaTGz|NX+CZ{;^*;y;k-z<~49<9UgjeKDZR+afDT=k8DQ$_udl`VC zJ!y~2+|u91#aspNQxSY7u^gv(Rh?g~{59-v`RWr^7*~4EE{>?x#|8_wtV8%DZE&FkQR< zWE{R`%sA#a8h44i5+Bl5u!Kr=*CJsIxVZD7qv29fz{wQ=|VdrB^k<_Hz*rE+S0k6Tm&0U3KcE)ZXeKDENNpbcGpC;zra- z7rnpBN@xG%TTr!*U%`Wz(DS?Z*bI}$q1B0;4pyX?h}L&HDbX3uesz9NpCdN0ss?8= z{#mW)AO)d;LH%BdzWHJIJ=X~&`n9*SQxaB@x6O?V4V?@RTcmX^luCI%bPydCk4CTC zml=AVOP(CkdKVKL`540yOt3=y58(TUo3IHBYRFjW4|qE@ok zDH~{mLGm?MJb27K4OWyeMVy{X^Wl zvBA+`tp^DR`|tYyzyQN7bYQ?A;xIMgeZNPUKYovYXywfpB#f;=R{C#zP^h!Dop=zyssp!r}KNTtfZnrR9OBcl-X0nQ4e#o+oi5_ z$|6r~GANTEE4Qh!d5rAy#%)ZbNgFx)uxrNqZP)lz^C_lRSuSSb{lk5M-y2JiU_Ud7 z{4o?W@H1?lNWj<{N6v*+Qd;iLrQtiX8rUDsz|(|yo9g7##VxB<{w_YBlPkVvbok{; zPmO{O5EOuQP%C%0TP61!75%oNd{u%bE0flEYCRS<<}eflSD$4qW{nSR#VK?HJ>l6h zy0dhV9LSDg%`Ypv=5i~g2iVL_`UPR$=6QU3v3;avLaMHjQ{CUbScQ{m;hc)=B~cBO zQ(=Uw(RGwuhN!lTJW@$Szxf*C#q>EjavGf08tDi9!CIe1)rLe-O!Zv1T9{4%Fv2i$ z4+-zMN?M8_R`swo7abKk#G?E5m@QL)5`;G?aB%w@J#Wiyz2rG5qU7$Eg;}D^_g&Nc zUs$xlH*Zg*&g&wG<5H~MY1g@OQdZ%$uhlK)ZyX<|!h9sseE$V@Rg(o2w8mZMcYddmd&qCF3c>9n}m1q7T`>F%sE` zwVzsqb3nQ;LfE?Vx01c^K0t13l>ZWG3P1rOV-0(>(P(ZmdhW)^Doz`$h}F=h4ylwi z6iZel!|xW*mg264q*jUFsfRO&BmV)Mjb>~@4ZqLhv$@oK9MF^;G^%~4r7X>!x;z&N{bC1n|;SCSB378oaaGx-Z@C0c9V5ygM5x z*a_v?e-O8yn*(nFK*u4j4D2qz(a^;A%Eqh#&uN-Qn&ap|^f|qxdVg?iPm1=%o+E5= zcc$~WB;EDkV9%JYfc|leMqx6ONQBrP&z@m;#P+4;GkJ<8FPXCRfoyk|L?&Dj2B4-6 zm~h{h?jAqL`D$o=Dngj6ipik+G75<+8Q-_CS5ISu3)i!n2)v zG+i_OOx=6!2Z}qxix_SMC<4;1ywgodToc`A{hX%R&-n$WF1y_`ZrYf5Vix+GimvXF z`83&NYt!|F-`-uATFPLwMlL}<0VfWjjXl0|&C?PRq_!IKjqE^>ZTB&;TUO~SXM?jQ zDToSLMrE}>nEkY$j)9E!8989!etF;bSX+jHAM0{NsjAz&kGDQ~2@4;?is>KDOM!220nZ5QmZEFE9j znUq50-AK@m=TWgsThjq9D$kZ_R;GGsF{S>|qOgumm+ zWHrGl4bz9Zyt&)X199HKJS}JoXspA55I)e(MA_RoeewBu!#9_Vo}z*y^Tg4fKWI}` z>S~1#7}k`5Dyd04*NA!P!7bgKe5`!Q{a0~9PeF}+2Wfu={z)gh-iK@IP&=P3Zo8%+ zakuOVcFxb_iSxTTkd}H*m-to{sm*DiC&ZKhWn}SON~R6{6xk6O-QtDIQgu#x zo9$i%8VW1vzdig`B-WyU_dCTu=1Fr~w}EC*8_*ZCgu(^Pf)g?*)Ar#zV@uZ~Lcgzx zLn@+Ws_{C2Do1FXw>R(A9L8SNYet^RjQWaeZJ$&Q8ZBr{e?ZKT$EjZLE`!2br(PW6R~peLEexucp_v; zhIQ}fO1AP6clR^>)!!mcttJ@gvEm9$lhLi6n0NR=jG+()xE(jih>SpmpJToC^kaBVk9KjJLi&467s_Dc1I% zxHWh}%)hckS7k8H#pQp7{5*cD!ZUXhn^v1kXtw*^wJ!@W3$({_QzThVp-0FuVbr!C zzbW?B4E{qB$g2t#Y?W>>P^w8b2Ta;~PG>tz0Q)!us!8WqEp1#Ig%9X}eH7fug`kir z>=}H#RGrs%5?P_C&LzJic719WP|9m|LD&t6aCjJO>s*V_OGd5{Yw!0TCq~2a2%3GH z$Zr-IOH9+4V0F8LE=F$1qu4=o#emqX&PsZXwXz7`r6y9+yevwX3!Iq%YF?JFjS%J& z1~yADMrjiQ*!uAIlGQ?4IR}7|-;V=-HvCYSUAZR<1@g4}Hlu4@kijc^UF0dF4eyS{T2&GjbfhXY3ZB_iccZi%FL zy1lglp5t0C@{h_(A|FyZ!rSL*xq+@nSqee{4v|WOodi=sSd0SghTGqjl*={U_^cPH zEhquT3lUun8tTg~(>5&3m_1(%JcG*8ZYL&2+$7)1Vr?BBIKeD@#dpebSS8(oW(Xs& z`QQ-k^~i9?Jb=OGQeCkz)+SG$^Cj&)OIJ$|tWq;EGL5G*S=O za096MlEX3^H@8V>W2o`(7LmCTLQ}%e>WxKI2R|>Rn(ZfAAgMZA@Qlfs@3R>*m`(8h zP)fQ@2vOom*!Wb{tBuV5Qm-19k$sycvGUWU3UhER=d6QRRHBvRGMDeO%*+gIz^&i-wPwjQuc4BhdwLs!#OaS<6L;{(0p6l+6C_ zmhUS8BXCCEkl@mjG`Tx`hBQ|#7SyMo9pz*b6GNEjxahqV2u)v&@^36W|hEr zowp|%c|#wP5AR?JCvaO6F`OmV+2^Q#-W$j)LBjo&{>S$RcDIR)qV<^W7!!WDxQ&sO zhTs=Lu4Mg;RLQ}D2kkQt@(|-tlvgRjX>aE@T7}#|_5xDFpC&36t472F@cs2hc74J1R|3_5jM=aACfb5W=fz_UFI-u6isI%3s1M_*Pcf)_OrdgFliK z#)5ssO?nLDR9?cJOag77rcPhD?1oePt7$DIkdDmeovznMrFXU1gfO~en@u%r5ILd0 zKtj?0=>lKR2uxq61A^Ey*G-`#u8;^ByWX5D{HHspHfwf%1Mq_R>UoX+I9X;^4&knM ze?lo7ijfy$2GQi-Q2r>OJ4j31;mtv5z&*uLi5cTP!j1cs5xHzqu~d;K7_?||V4(xT zUvB8_j|%r-<)4d@zKQkc+U&Y)Y3Tb#^KL)f|Le=5J@T zb8VC>cH)Ny-n~p}AS=qJ%bF^|gh^A+bM^2trEtg0fKM{&XPrt?Mq%L&<5Y??UkLEB zs_ofadqmGgOA~Kg%~e%59K=rk^<(#}Ewaks>p?|~T zc21MJtghNYsFrS06-Y(Fd2#l|GhEc=8X~dDu?kol^B?2@n^D&Ho0YvUh(UpRwSimJ zx=q2B(=p7}wdU4dc=e(Nv=TIgHQH?!?5J%{q||0;+ka0mwgBALxgO9KLV{5<3fWd} zf7`2xZCqI#@u6h;P;sgH8vD$$6fvu^)V&VV>Q8Jw5#Whn7%|YYQKSRu9Z@)4zUDg> z#JFPXRdbUq6FqWNJ2CKRERdZ+vb%JoN{xldpGFIKf9PPNW^8Bpy2XMHd}gSfFpUCj zzD*RJMn!nxD(kvlwy8!h$T11Z9LE->UG^y?EaI5AktGUy80F`P%4+z$wh2za}S8_F3Ysfe4rP88*%O4%`*$8Fm z9h_Kl5_Qz!Z)&u1DHc&NfrmE zv}OEloBw)A^y1j76O~si6sB@=LJ!YT_EY}!n2S;kCv^4J2#)&J_ifWkWI42smeR`K zM%?@aHlwBd2bCy2`7cLbYl8{XUVpQzHUtaq(duwd;$=28g2sn^l9YRc_ce~-*|zt) zUt~Ozy=fvaT%64asaY$|?;e!?rRu_eb*1KsfaH$BK=iN6VygKeV$ayPXS&OBzTKLD z{%VD;M`7RuY#$GW`M9}?P(1fkmspGu64qnG%UzxrV0GYrRy%4S3DL2j%!r*Wq#>Be zsi?HXDqX8@k;XtuuP^g_s2=S7tX6$fo0B#rA%c}r*K?Fhg~MvgdiPsi&r=kIH7;ZB z&%;dkk&PvHW&5J*yd94Q2_4_uNtDW9fENCLEY#Qlv#g%(i;GuzNPv4zriWdDiA&|@ z%SvIEZH>6le>K4@42*#4UwG`;T_i|JaRh`dppHz7R->v3*U*}v zy^|~82%}&p;cfgd41BgU2hP`bZ&CV8SO(0V0Q?N8UfU|j?4~Wmj~Pd1 zCVZq9Qf$2$3$3cb4FpOJ1^FQH@JRc?zcXXP3Kk!0X&J&_1#ql`O(dA6^2(jWrzZU` zb!KH~DhPP$GUuf2=@SP~O8L2d=I^jCP-}Kyb*V<~d2emxYR@O_rLyu+AMIu0sc!_T z;!Hkn#z1JA`Ud_?3t{~#ENNBl`sZkg!wku%;T)}&r`YT4HyC<}#I{r87aO;e|vz&(fDnjQNn&{S-A* z$5(eerO0JMr^_}&Up-|=q&}o5M!Qk4C-&0I${aKt9~T+6)d(@8P`M>(BE2u%$D2-3 zvQDg?H}0%^_ANB$#63Mv2DApN-OUJYk$2v7ihM`3_BoY7+bM1#Iko_GgR7K8gLhmt zLLdc0X8M9zR+bD(Of+dry_RrCm`xN*TV01%5jj_Rq=fP#EtttVKs-ez9ig~|PEy3i z$Mrl1xYJIp`P)~3qO@x7eg9e2mt+2k@yP~q^G+tgXUb`liKH(tyjKlYXoaX*^F*m2 zX#`5-H!x4GE^+h|RVazfCgzHN?xIVPPwBgpm(tD$aGbpL}6?yu2zP zz>N!T#ibv*Z+oS*o^FFWBQr7#IQ;Pbr|lYRuHlkquPu`PtM@Dk*o4e>39 zc0uBMMt}u%VMo4vZTaa|-&pCuSa8*>U)B8f$lFzcv`fWv@{r<~Fy^5SW^h2zH^HKe zb7TL9)TJHpz%FoqwD*CC&mI4$MdHZ;m`FlMXrH_+9PfVoF_hTvx&Gj zIiJM!L z2v)XNX=)LM6=jtCKpbUI%;owE8kAQvzFucFuU}Om7p;VC4Bh9SzcI!gi{Op6CnBmI-Th$hqWu=&rG2+L zL{rqrI|dvaxy5kR=efQTD$5Nr^4;_=eM8wjD*54!HD>AXSRZUcLT~uHc)q`}QBDoE zj{BA1Kdie>)4lOXfDyX!wdZ2~pZKkz30}lp4ATMwobT0yn32)+nQgrKQ+rRhex|S` z(P$ah!VEBtRzIwhzeS}QMl|ch<7=YjV$RL=>e{+LGbc~0lIU=-WhTPDyK^GRCE5bh zsaWk9iX~@`(zj|e5@~@xKF0@u#$LbcCLzCNYpI`;5nvS^MEm%v#8&^7_iqi zt1fCRB>Xb z9fgGthdLQEB}8)XJ2msWIMkTB55HTnfv_pfyp;-7jDK$x5%s=F#Ky>gYcZd6Lx#uX zZ_BL-Nt*M-$goT0{pX8A=3-XAKR#=QhRsxx+&1gxwG+`G^4mkT);mdp;W0| zE*Wbcp+canu+iig4Q}S0s>;IEOu!3`+nnbp%E5^^E>==3Oo5KFVTqp3n#Qr(Y~uMWGlu=K#T^U z@E*eI%8=c3?Tw#}eYYpaaiFli4*#Qz3OSmnq!odLR>chV zUunAZt>8%+Gpgj-T#{%dQ3Di~Fx;|u%c}<^@JPqQ^t9jVIiEa}Kuv|%2m9nWvhkei z63aAeuUZqn6toJokrw@2)y62(W^^npAQ;{_DiS}GOHM=?2RKR^TdE|B^f1w@Jx4}c zeoP44{Qh=4_tc>q%CtQjZ1z2W--`-S`kb{@@6Pr&l9fwzVt1qyFK8C)8J3W^RS+X; z9sf$LQdRHzC6PHmX3~}cx)tx;s=fF@Vh(}(q3rb@dUK&5=rHdEW${|;YYt=VUFvbG z0m-ycq828`Z1aW>Ga+-h-&#nZ1K!e)n3p6Tt-NpV?ntO)1h^ z{|TJZ*mL6A=Om)?oPbLb>R*r5Zs5I?kJESIWpVo6N3@m% z(3X04oM{ElJM+_gq>^nCbvlU0TM%fTBpXTGZ?tYQwzoSDpvM~YNb&GHx zN+KVb?RXeKy9R4yeNSjfm~g1_rFgdDw`|xKE?Z?at<&+e(Q!XIy|#pTzY2)sO4?wS zx9YrK4cdK8$nYxKU1_H(Rk`;lt~z9Odq&-9c(Y|h=}XG;K>Ld8P%JzC(v;v1U0rF$ ze;XVv&KT5~ovLyIdj{QHCmM0+C;79879nJ&_{U#U?ry0#g_P#d`6W_vZH(qTmY?`z z*GVHgK0qDCM0m`WOeJbkWYMrcb6nh6j^+15M;e#IA<%1kwO;wP*nm8Jl16fO%23co z1i^Yz1!Ok_{(UE9GIVn%EKr>5Aib0{ThfIrVsGiwB$%vKC=9X;PI~UqNIN7&Nzz*0yL__ePC^~w&52GyP%L?v@&#kdXkXrQ?C>oXp-)xg zz(5uDAda>}q{-JL;o3Xi=GyCJ#5WN(z%N#=a*VS*ZRF#JDKGF0hj}?wUkD1Z2gB zUYMLUqLvhK-21j))!jwY{|^5P@EHtra}oq?(;$?P>dig29u=Hx9K5?9^m}yiL|Av; zDKht_fi`A-%Q|Xk`i|3ie{h7gmZF$kAq8oJjcg`1aYx$?Eze`v>3kWcCp) zLO(fhALGE@B_4`c#dAx4x2Y2Cfm!*wnPPfF61qy(I@9{A?-Vb-@(Mc_jh|T>;lC3l ztFdz{(JzRqw}DnQ2u&gSpW|-C+F>+@HlBHH9N$)f*@s?eYWKBUGtJ=M#!%{dG_o7? zDWP~y>s6=hLue-v!Jt~yENhYcg#P`6bm|Po0Ut`6uVm(CvIv9}{gdbk9Y;AAtsdw- z?@e^nEL3b4b5s0R*HfqY1&6tj7(_UFv?q@27A|?3gR~DzXc?G*`OiH5vXLrqJAN-v z8EuaQhHO$rA>bv&_U-XA@gd@)DwvA^v|%IkidUT~%T`Fb@P(|AH#~FNadRFhU>90~ zGlwb&L_yo~V9R_ISRBFp{SS>`uuTo_p{IG zWLK&|n-Sp3dB=T;o#)tTI^Y%fi`Y_Up9hpAjZs^spPewP9b$J2I^*%=oyIIRn&o?qe~Ia!js(5XKN0QMT~vBJI>C=)Y&(Vy zbKnHbe?u?9$@i;e;HD+B`LrxW#LY??BKE-bbo*t#$|oKL74GQ6BHJKpugeebVh?r&RRL$COhM=!X=- zJE{G7Ox9DLv zE=4&-BsVwNY5E#*G(v9^hA&41lCWV;z_(8BE}4i?;V&VV3Ryc9OMiKx6CHU-KX33n zQBg?Q#f)XZ(;I608*j^q#yahK;bi*o>IN`IvTeimobcBGvz-7Lf-!Ty+ z%?d5>#QlfQSv61DQxnpnPhSy?MK)8V;5DSW%Qxk)#xtP?(%AV8Cjp<;mv<8BPXdSX zN4z1{Nd>=}9ww{E@8b~YCj~+rMdHOU)?&i8zL|1g`PvjXH~Z8_V^?9M1II)2DWfay zUQ5}|gBFd`cK(V)>@19hV?RO9!}XUmiy+6DkEp-di?vgD@1RFG&U?(n;##D=9&yw6 zExcWN)DvYQPPb|aBpiKPguU6pWnl<@cARWlR-|T*!(|r`TrOUt9L@1;>@_mw$LM?L zd`bp!V;=QeTb2yb%!3mBm^)AO(H$&mPHpv_^f%m$0j=g~Xo(y*{do-Y!YF;1e-mh+tfx3LymF zjmcTu_&fIOuWUn%hT@^~a7~v`aMB6F5PRY>=f&*e9bBJmLP2|bZf{42c0Nn790qCh>t@{P|!^V2H z6X7o~xqn!?EoCX_dR>0HCr7K>wiH|E6f<=A z53>>cJ73)tg9x5sMkZ*dY;g)8e(xVmDB)wYwT0B7)dB99fT zVVe?^kmeIP&zjQr)MqDF9+(;K#=0a;*Uy+_L*><)i;nqr_06+!XxICdBBA18H!0&0 zH$YXnA@kHwuAyx8uNNjv2dMunayfnn*I_}@0zxQ6lm+7@Ki&Mk^w|+cI>||t1BRNc zwuvaCwsSD`d9z(jnQRFi`eE=M$WbY({^Q#Y1qsR==FRF!h8Ml#*+BpOx%GM+H+j_g zdu9mHmifF3JY;yqw-AN6SsA}t! zI5;wR7>S_HQ&~;}UL!(qLtrD-W87xa&#b6rueefnYu$-DNr1D-UYND;LMUv((80id z9I>R zh^mo%zCrl^+WQKHxRzjBWN;hY-66QUySqEVgF|q4cL?qlEWzD1xCVmT;7%au9nO1y zaqkcG?yfHBs#>-7{)$E;&69v(Nc#(}+4|9h5!!+wli?biX$%$q&%-%88>v+|(whC# zCl&JbF|qS*a@LuT@nVibZbJYR))259D-Ekpsd7)_cA=n(kq3bm7r$1=$hTJ8xh%%)DB0~}!3faVvB05{SS}5jry45A;x>E)6e)&fQyc@Lei?=@Joon=nMIImzDIeH& zh}!Gm>MIjMS;cG9=Jt7Q7J2B(K(^K=uUFd(9)y;wA#A@F75p4!rtdbzl>!Ne!aWS( zrR*g5eb2S4n-%}u(~HDY@TpQ!v{T-sQQxTjS27g+*w;ug!}sI8Rcr~<9k5F4^Ex~{ zCquhJVi=9xx1ekqC^A%ID;33S?&elvc<-hZD)FjES7Tr2h=ehPTZ)7U7!BB)o}BiR zi)v+i^nMQ6f5mCN_{jP#Jq9VeM7t(X@--Br};U~?m}T}t%GvC236o7YyIAzn@ zVKgwfW(buW1PO}|XWzz3*cbnV>XvzED0(qmT?>Y)_->y}wdK*5bEF_anc#mWHAyLT673{rerOzW^?m64%s5q0%-Sni;jkO%z zEl?w5CugIIsaJhAc9^Hj9~asI=!G^?ER9)l*qe7b2QfB}6Zbxrac%^3#x*tD->=U9 zVjkAZyPSxB?c_Q_dNzaq#15_*#=by)$~;at^lKzAYPVN4sYHj&rHpz4K?>c@)cS1s zRup(kV(tRduoeZ~s=HrNSKmrV$yHl6!5DiF#4i}>uwmk&saarXmlVGlPU$npo{yKw zFw;o!Hzs&tm~FF#Zz)K!bzdo`!xMzpI7kQ9M+%q7hwfQLHI=@$mAlN~DFNYh;DTiy_nWa)W4we_rGYhgzO zXqZO`p0RTiUwj?mpc2adz2>Y-nwWy5_g&i?Y6bT#PKkh+IN1@fJz^aes`Bba4g?(m z=MmWmp+<*$$xfjreNs_j*FRlYtb3JX58!LUa*AZ6Ir}1ADhzk`PJ3pZMwEJU| zOAp6b8LGnJnpYzFD9EQIza$Kt@w*lngHl)*TCt2x)PzB;V=q{hAadTOQooTgE z`e`GK5X7l@;&|3p>Ps`Cc*(&dMK)3#K_h%}@@K8Dks{)AT`Q#oY+O}w95OpxFLW+*Plp!CV|PsasKmq*$+f1xTI(JZ{oi;uF)D|HRSS)lHr*RX zAZ(Rr{$3+Qy<$+TgLALP3iYa06fD5a3#&w1{m82#}OAzDLbN}yijhoN9g%-~M{75!6; z)8i+V2I#sWXkLvX3(<>fr%bKc7`)?pY_+e0g8Kk=C94uI<%Q$NO{+$6NsKE{k@Qle zTLo&a8FgrqVY_2K>9s>te?=TRA`g$#R?9g-4i+!o_KPh9iCs4##R8(4@OB^Du`si< zyR+8k^dx5$1ZYc6s0x4`)8OoY&52vNw4F>9UV$FHSGlw~TI#pD#AihG+*Yf&sXkL6 zx&bXz>~a5C7UPJ{TzV%WDiC|jtEjoS0Vm=7=~Mz-I*StfAhfxXh~A(MhavyzI%p_` zd)5L+s=lCsXqdZ{{+yz)*!d;Xnq&b`+v`T%#fzeOK14)G=g2c`iGu)ysbk6Q$B@Tb z2&gLn!+9ZG}6TUT*3Jj8fuMG2ntlHJrJ*e+*JA}?Ys zuSdO~;jIl)EyK1=sC>&9zjDpLV&%D~pzhcHK_NKcIaG5iSLv#)ERsZ%)@ftio0R|$ z05@Ax41!p%JS9Mh`KQpg*0KcXYfjlySRT6nG55*xxWfnS*Jk5YfwosW#eo%TP2 z^7lGL27Qrya~5@JcuqJ`jf>i2v^3YUV1bqbqAY*ST7o%& zN{4IEs>P7wV&rk(=0r!ez919{dnK?boI8uCm|DS>j>?75Ecjf$%3~RuI6)fn+@7I` zYD~y*J7#J}Q7uC+tq<(^I$?16zvJJNoBdS}dsmMm3{DzE} z06kv&F;;MQx6s9A)z{ZKzVi)bU?HZhjvx(W%C2v9pe*TMslK1T=Z%j!WH;y))BFCd z-Q}#69C!*(X1ehz!nmAiclu`qJ`BMU7=DoT9>*qv3H*%}24h`7{V{EPhcv{;#Ne8@ zb6Rag9!bn$RxeGVg*bO5xMRI>4>|d|1|BHG506%uDW!O~{E@%J>VN%~@c!?|GPXJJ zY=~}suvttrv~(m=#*zr`EnGHL17)W1ys~92q`GM`f2zH!ZqWL`uG76B8KnrLSMG(xX?) za&>ROZOmgo*Ft!|9=;|D`_pp4Hu#X{^{>h;QCRtc9Str*aLn7ZL=ADe-j=8$I@(qw z@cUwDuJbDIR~PDG$^xCDL=ZkJK_mzHp^4kE`#Mqeoai3{hs`RFpr1QdoAI~VJ5SO= zl*KKu#L(H;;E^B=K=aY`yT{L~l@No3@u$825pWsl61`&~%MHfea0a(!KfN5NZKX+I}! z01aNETOmvHPn4~Hb?za^S&?7NbJx&7;ii$819XUI>0+l<0S}$cfQJN=S478kUSDxV zbt1z;ErXktDmnR`t0aJqQ}&v!MHIas4dIBS>k`{t5soWxxnk4hsLym`&f> z;2J<5{_NA?lphc58_YTn>?lP!z5|ab%jP8(`@TDTok;ixfXf2T;#F3EWK>aEd61Iq>)CE zzeo8(m5TtFIQc_wi4|9A)uYyCrxSQqqVBn@7kpfY3DP61d#<+o(y_XYo`PWbLyUXT za@VZ7WW``O9M>xW{Ro#Pcbl!J&-gB1MRRh(D6x&%2jud8e3i}E`NB@kRWES3i&W6{ zI1hgFFM=!N`X>e3f;C$ReyGDYTlZuB%dhLV3{)CGG)<`B2}LA#an+*n1T`3Pgn?(z zt;E5HwXF?`b7zFaLGJ{C-w$|wrxN5frGWbGv=no_ht-*BMftN>zAD@6TsnmQ{A4|} zqt%RPb&N>Aom=B}gqnzhiB@vyYEW6PEYzey?ziXoo`7{^uIW+Nz3ACu)b0z$P4CQ0 z(*~G}3xUAEPS6l*#2FHvUNh-k1$Qcph6y%j3mDD1fR1fpjsw%mD)&QMZLj;mt{f)6 zbxxpuyGf%tO~7bk72IYuZXk{5WB&kOee+B5{TbgtW;v-m=>OnNZ%qboTRb6jElCfD z50m^ROh3tuYvGYCDvmN~0oR`^n`s;HTo4TyC$dM9hy(#< z7=OW)edDYpXaiOl(n9XTb0?3p!{*V^*kXso^qf80r3&Tq+v zvIKQie8Ai5ha!`1Wz2S;;L6Q^s)W-6y6kyYvf8QPjJdlFj6cbgE$Gx-`nCdv*CgK%{$`Re9j7!k_EdPIT<=EVt&I}*#oKzZcTw)=$T#!KVRI7$a}|&=wvrwv z78!wOwZAY!Td+GBp}7vv#U|+0&>{>{Qu5O}JK8b(pw)Xg*r=YELNJwJ{!rGt3Rqn zaXVoLNfAC_g+Ti(~?e)g8Gf>5!yo=fz0C@ z>n6)Ok`2CnakS$?Yn_ak=%T{FH-gl;I&cb!Zu-nUJX34Lmd&2j%?8LI1*c=bE;-_R zC~4vSca*=F5l)-y@;aJZYO;$$ERntxrjhN5tA2;~C&rf~<#fmPrx%nH9~9aEHaN$Z zk0ajtpgg$r44f_8{kE9qno8+=HpG0t_O=l!;YB*}+kr_;dl6lrKNa1YJW0oE$TPs2>#6%+r!Vm@JYUdX?m?kUBB;BDJRuP9*DR;4s#t=<}lf>H0l- zag>RnN-ECY2_^X8qoL^fkIH&AGT_$;j~}AA^wR=$Hi#bU5E+rFeV;<|>0N7EUQw)_ zHbhm5^{_DMvo^p^LfP4^>-r6HT(?nQzA)UQe_RwK7gi3qE&5xMq^&N$yeL3S)*ROi zR~dwAkLWkWm$F?t`**fLs}T`1rVe_Ko!pL@lOW!$SPtEO)@55O69p7GDSAFpP=uVbv$uW~zE z4bDlSvLn4V2b~_UMiv0BHj}HyPcv*u&Gvh+_>#l(qR(XG)U@NkNn>ms<7mm!NL%&g zHmdysXf?W`wsvBA^1>!)7nyIB0EOEAZ)n}NrXitl+YswNeOD-5=x6kEk5S!*Eevts zh~QQa$WPlYknC5s+ElukP%I92H=P3u?jSKo{>`2ymhwhJF2^Hqc_L&JYG8x$fCnqY zUtDUwIlJkjkDiJrbP+pCI6d7vv3h4?03Vdjgy!#*{N0ILt>DihKO*1)n$dW82uVm1 zWZj?lhrlv?dS5)!)Q}Y9vP=_Z#`-St-YU4Q?Nt%^J%4KC_f|ynMC|hWH z>9@h~Dsj%2!gu5;wey+Y?aw=Zp;h=$J%U_p2ow$FnJC+vBu_D2m>QGSpD|VB*G{ym zvH8qY&ME0R6gYTn^vQuq7}0fb9Bh$9Epxs8o%=iMbaNY^r&o`TA6__V{`)zly*T_CSzt!pqlj$Q6`8!`gFXcMVC^J2ANt;)>F_Ug*@@-#zzTD-3y|N-JGGI&L<-k}P|u z1_qdm^-CVg3|UqZ_&XttZX3=yYb((W=g^;Uq}6{2(F-akWaIKOV%yDuQ_RC@gW^^8 z$DsPw8k+wS9|VclH(6%+oqR}?NU1x15?>;;DRKG5wnC+{+Ta#wjl9-?$?$*d+vm$j zw`3sog*=XSGsfIRYe{!>5PrP1_3iSQ$BEAm=C{m{Th0tt(!pnvwt>XGE?N-N=y-Nw z;N-238{pzHc_uOk+*zAX_l4`i_0}GpKUs{CXKvT67IUZ>xBQ@=EvGbf0nf_nx$3O9 z`Z4O{RLy2&M*&YXQ~yn%F%^>+?dqR?g zAB;w(GHC&)O=f4!AJki5oMYNM6dk;O@Z^^!O6CfZtuZ)L*Wzu(NVyuK5LR5~aR(B$ ztEJKiR_~3@5oAF8!zS&Ntce7RAPsRDVe>Nc4ZpABAJ)zv<+FB4@^3#z8Q6Hu&Zk0S z%AFa!?n&R!9jA=R1$jg;^VC!Mko&(^6}c7Vp^1Dl=zSKVlAIb)&Ch8e)QBFXE#n35 z5$yMrJadl@?H}Q=czoTY=Mrg0KlZy>6dXA?5mHK9L#poxJxB_CEcQ8a=`wYwFL~gY z@MtY?=6L`Ezq$=t&ts!mdzCc;JCzkC=mGSq)4R8!k6skCf zgNuUev}*eyzkH z-fnk&CMdX|UDHLE_+ubp8u)=7tMb1|N(*Kkwy)K?OD&K^3lXGmXiVT0*A@rj6!_g> z={U+@?40{hVb}A4THY?-<%kVaY+cQ*9L`m$a)SoF;WhIK)l}iaMuOCHXPo04y?!1H zgy*8dGK`bEYq@PZ*>Dh#i34qPiGo+yW&i;oiC^U7yaST}vEy$kK3h^E8WiLy$g=YE z2iRmA@_C7;a-pe`e=HKsrZl>@SWC21KmT>8br~x5)Ai*vY?Cow@qH9(hJ1HkqfR<+ zA#~P$0EyUdl-zNFLDk)t3&>la3@hE7XZmKdKlm^|hNI6OhZc>jNs0^4z@sJSy^qxF z%J0Ufh-~kA2oso^CC&x}>{vD>eR*O)ezWz+#?1H?lSF#n}{5alZ&(bNwQeT*9YW!_lx}KBvI%n&h)u8h1%H>$z`EK7S5GeeERaV;(h2 zkMP}mgR77%mlJMrGB;&lcphS`V^#R1Mnt0o0`9ha$~j^D*H=ob7So)2no&T?4#Q*0 z)6&*Ru#4=NtqP%~Jfg}qQ(~4g@Fe*2558#$dUtfZ>I$UpS9D!mz4(G5`l`}9E^%EhdcSlc0{?=2oJG*iP)|{Y6G|X zASY}FId!2h;3r)Y;$Fr#){ZrQV9FWVo*)uqqZc^S$-B}_;2XH z3*L{8W)r=t9Bu5{XW7%7Su;82?kQU;(GuV%q3RyWRSNeSM1B=7e94VAkOOj#d*r%w zG!?#lrC8t4`^SavTkEyuyL1{4Qd-Zn`<%SzL-^1{5jREQKjr*r6B6xcV~sS%Wc)MP zx9+7lw%oSNab_-}$^PSB1;D3l+-s!!ItZ2jZ-yYrvmA7wqZw3A2H%8rSXA8FYZP9U zz4apTXvDOftW7)O@O(RH*F%9&rAl+X^QjW~-cMHA5V}4R#(}%*81=O^Q0qJd#MYtw zx4%)1@WMqo``=GA0isRM`u?8bVh`iJ-`VEy){0bAJftg&ce4_7vDbwACH9$NM2pPg z3(d}obyHmL-F1+F*7IkPKJ*1}wL^<+st%MNx?&WHmFu68LZ_hG!1rmLb!Q7T&`#=8 zj&a~<-h4O*HwNYcGq#B{WUjO_VlMx0Cu!sX=s))0d(6THcZBqIR$F=Ul1iN|-Wp;3 zI-SG>fiw0;BZfgvFP~YRs0V|Cr%pwn@g?;-I8>SkDV>O@(T*~v8u5sc#B=eRIFh{A znuFrV?pAI7PKY~T=1dD=qT41`iQH`Z)o^b3Fpg0<^?7D1hp#ESR{f+lyp9>yI6D6vw5XSo{ZJaTH(F{u(5|qn7uM7&xUO+)<0U5}B7qis|O$ zTkrT!J@nSoha*#VixS72Om;~sZxEwA;QUv^Npt1f;f9;pVkn?xgX(0v+ z72L9%{1|h%g+0he*%#cT+dk&f8C73S6g=U>6%D1AJjqt~Td;oPYrzjcA*!&>owGrk zF3Lq}^+gTIqgq0)E$sU`>^ZQR9CIp9eoow=Xnc)F{<0Yu@9#1tm@^?J=N_LauKHzG zmSR@e4h$ex>X85HZ0G2HPBRxLu3x+pppHj22MoxIqQ8q$#V+S`|Og z$b33RSq8N_`AsQ@i3}JAZsX<;1!mc1UUVqvzuy&>8&SC6h%+(`TeDWBvp;^l(6`<9 z16LJU0anuBJF{}Y`HR|{ZUKwPlRcI7P>Wu-K1dfm<@Bs5tPfdhGu#h%%&&PQ{y440 z@y+%+4n`d%+=>;^rY1Cgk3$OBT)`yr7R}n|foL9V<*@MCcUCJJ`7#%Fr{j>srHyl- zpNzNFRmGH;Uj)97D}TktRb$bvx?|TU_!i<@1C}yUjbi7y$h!hyMwO8O+J&uAatW?Z z8)}Yy@6A+=4e9DZdnLv^XebcEMQ@1uc2=U4NPiCe_88t88}pa``v;ii1WtSp3Fr9Y zaFdXp*!!AMtr?AG3I`Zu$#vO=_`0tn1%l$-x!qP%$uHuRG;sUKkg4 z3Y2V&9sz%{-i{Xh;lP4Qssq-jLTI~EGfo1!U2x$;{i!eF`K*4P=fLPuRc16tB{S8R z1AZ?So7{rS>zsXYP_S#7EuHi^xkn)xY#oO&D<;gJWiT4j#X>J$p4U<_cGz_$EFkil z)W#uXVcC!+fxtMbHWz2bGgvIkmx^Xz~V_m$&y4h>`DtRi~bnFz=^BBOstil6SqdxP- zj{-08W_%BAc%~r#QMEyOQp>^J;K{^MobBx=h6MP0DG@sZizoyJ3B5a37b$9BU~ktb zh_mmpu9Is4ifh!t@_?E4ZL$fNk9+#_gWn%1G3fKNu~(c&M1yJ>tsb%9xUO4dY2Ra( zxn(%&&CE`AOdkwJ7}iKVhY^soNYblDDekdu3l(WvB|a#G5Ku*sxcV_b|Pa@ z8qpMSKTv^B=slyz*!S7#&r%yE?CK=x#$H8Od0rtPtewA@9-Fg;f9JtQaESc@<;9*p z4y_tT42g%zy!QZi=EdsV&B{fMA!lk4bG0U^g{_{BIs>IvLcMj2UBd5b1Bu02p$Rmr zOZOrMebW6z#T^9e(cfa11rKw(_IfLBCBZPLD*CvKlkYnLN=%HzE}D9g#0=+XC0*W* z%1QE3>*6W*{C!?WLr%3+u;78b(VT?#qBUmOhv+z~1NjqbFTJOi@D* zOoA!@%%P%idC0@5FvJUG<4q#@Q;mtnlu#XuF3ei~CGy$D*|TsZmtPPFjgdzA>28_! z(ZX34wdaCSpUi0iEs&~qtYb>hjVLlcn?j+CqFzq?)sz3UKr6E zyfc{fCOQ$@q6+(ZxA6Ir^)G^n46Y+z!pW+ z>Ty*UT@ifKc6fcYA>(#!>nD(Qf`k`=~=gl=dUbGE}QJpSAzC=(l1 zbXE)YXrC~^9?ci2D}b?LHtZLB7$=M)LA)>~nq*RLPm$D%~T=F$T1X>}u(<;Pn_8K)h|PjoORVTKtAJ zJ0cZA`m_?JA|H(x7U3gN#sR#VF8$aSHzAguQfoF&Gwghi^0fY!A@$`oGQkq>kn>@T zLy#I!Of*STZkFaArz_i!!(Uh!=|(R6)CUGio`YfH^KEOL4vHKX>pQ|Q;%kI~L0XbJ zdPSPs8QVNSi3W1UZda2^Y$|Y+ULB^<3QTWVN1?lN_pO^x_M&a2@w3AAgiJxBh<)zI#A;PzAK ze8=bToXx~7XL0Mw?k4_1W$WqH-T3U=^WmFrTs^$(>wkpLCsM0r;^dUj#51zvreNgGaEs~REE>Lg?? zd{l6fEGWAr`2wG+fcw*BrC;)QB=W994YpPUJ5IQ8)iEgS^cPg%M$s#n)c+%Lc0T_T z2Y#nVTt#hpf5FYh1a~Uik@x*9*cZWYl%puK{`O9dA^rC&V}A5eiLbUO`zWaxxaXU< zJVNIKC{^LQq4Y>3jy1kRJ<+mqO@9{(Qrxpvj;u(4vS|)$7YY#L;UHyX=Py#VbQud* z;Mcr#ZSgHNHCglUR{{j5En~v}(r&QdnQTeV6FiXix zN-VT1QWPU%)j!HL7O>9hLV^1S;6LIF@#Y{5bzRL0W3vgYiHm!pMa1RFy!g*rIPdZF zQVT^9%7++m=U8d>`O}0Ghi3dd@O`KEfH$W8ha6m3RYY}oP+VZmZ4q%fm&cTX#Id38 zHOt17ybxuz)85Ml#-9>`=LGl44OM7a`GEfo$y+jKlRLl}&(3D{e6;^N zYyN|*w7Y5$4&U+yWjH9m_TOm}8R^VdD+;s%c<(@>x;ys+NAZ?eHNb>x*E(jR44Aot zs-#*SgoL^Bb6|_x0{(3D0B`VqcV${$B~{kCR)?51t0 zdUKa;5ev=CjBm>-a}E||JWo+8Fiz(KLRjy6gU7o`rD9Ds!2?UYON?Q zJ|72fmwLw%gl8v_rDgh2?x-TkD<^B|^qO#sA`wUiv`Hp41PSI=efmu+8+E9F^E-C* z6v}HSogCMQW-ROrjWx7&Pi$=Bt(_G4svXi>{D4p{ecX*{Hlx6$pqVxtu{Ae}g70s% z4+WTj*KN7nc)821s`TBHUVXWI4{nS%)BBf|@jJ}$-IF6p@n7Kl{E1FT=EP>G?*9iXId9oqs&HzcC*C3oMBmY#0s`oC%Y(qBO6+ z?@pKN0pB|kcm+)fMAR{DWuwl>UCMTQ1gHfykzX%#nVfU3;M0f~h`GV){l z?`fsy8adhr>aqktP5@T0B({y19X2wRsf8aT;U7H0hJJUeyv8Zm$thvbW6hG20+GqI zu{%<$YTVNikjGd_us^5? zGfZ{h_#BZ7tZG2^9P<8sSI~@cxyXR~+CgJ^e=6V1@O3qXx>d8IO=1?dleIS#0uVwG zM251IH!eF?4V$~(rnc6Mre4II@9VHJV^rJfrOCEvV0jKIwi!is=Og+mw;wgVU^8C6 zpZ(xR0di0MVq%c-RAnJu}!QGyw83;^CFURuffKZD5MYdkz-TCe=~ ze-z42(seL2wB_aqMwq%@ZH7i*O%cdY3|c0r^LCq#JN(W)IA0^bH`i?lX7>26*a|zz zB<=u%`c&b`WF?Alo)z!5zpS>ZoNPVk`GOc*-mP{943>?}NfDm@cv=3gu-%T&9@!{Q zPX6LdoF}49c*QiQd4bK&UHw*AEOf+aI-7<^1R!I@3(omI7ux;n@;rCj~0qLd~N_SeljNh|Aw?3K?1v zk`s7#LASF%h@pV8DB$C^5qbCzowv@xxrBStp9{N)|8Z}X3#H-LtT)Q3q$@<*O2R#+ zoa1t7FV^awIr;tPfz(;6-Hlc`&GuJK`tuj9cBh#E!aCANK>*pd5M=q8`u@OC(fZx> z=zL+0tWpq(-m|{>V2uSsNAxzbX^|od) zZw_t9U{#?M4Z{j$%XKOdWyqY&*mR; zoi!Ip-|UyeFv+PaNNXiin$etAJ5}_XT#TLUzki1iw(ZeASg!gNG9fR+jZvp*cE}G5 z5^V!y{ZwdnN<}++nldQ$KGnu0*Q_G9@VvMSy4adBz)I?Lib!eg=R zrBW~-D`1nD(2AUjMyK|vzf$r?@{L;idm|;#gexYOU?BA%UU8ydLse$y$wx~ zlyG>WmO}e-LC($H!ZaeT*zskk;eTWv&^Of76#QDJutql@-|IOPek$hF?+pxs0Kig$?OK{T zy|)pr>&@+yMPGh&*=Qs^vr{t2!Qd(}Hnz-_=k1l!b|pZCrwKQOYn##gx>LQy>&Jc^ zVP?Y?uXhVchWv^v6TB!{Ggu^xH(j@O<2IG2zgP|yJ1^U*g0fcv$@ySlRw?DDr8)f5 z?jG)K86J#n-~MnP+dF;jPM{IIRV-$BC`oL)9u7a9hP)+&7lnY5pcGXfoNW`jsxYL6 z7JBZGmhN7&UE;6T=Zch9f*p&XWM1_l7-z2`G>2bEs5u=BJ(xPV3NA4T0=76HHaBE6hgoC|v>v zFOEtF7bmX16*MfyR0}#aNiQiF*2}W1-{ff4k)VKhdQkA{G>^0u=RO{2D(41H3NyGS zW0tk3#;>WQw9BR`m(~MVTE)R!Or0j38NB?RUpoJ=e7=m&;nQGf(wVbVGHw_|NUp{F zp}p^Q1qBITnh3r%;g(iIzO_$l)wP`}uTMM|-HNy-@iKfmpVFU8h+V~=c~{-d>m1ke z%5B#V)=XJvxUWvoSI+{rVW7ZDn2pd7k!IC5cTmzTqfy|m&3{PhqI8-q@+eAkL{j!+ zp}g#2$4M=jz}#L$JH1mYwvhW+f9|tV6JD9Ugp^6({8B*jx7%Xvb*Iwp+UdUI7#rIihBq|I?wQeHSNSXZN*}gFDH;TC3n-Ln zjgtiZ)Sj=~xXQRY*(?)Fk1M9F_!A!4U>;l`ZaSy(R3pi`fM z&}iNHXLu(5Vn*jZo?8h_uh*wfXX)M-ww{YOxcor{z^vMz^LS~?U2T$MK29s>HhGC}S8um# zjw|?ADG*vohY-U83<|;p=t@k$@=#M|;b(izx}7w+f1lNThBJ7eH)=X6hu6ah$^TPg zFU7Rh-E5Qty0=X%TQ9y=@9}9)V=`hW@kmrlYXaidJK)i9gO3Vq!-b?M^_?5v_EqCt zFfw6jc5+NQ&16w&jbHQgf0deY~?|bV82@9re9oEASDmt!tOF)WHLNGat}$>Fr>0*7E!z2 zOZ-(zo9~=XJozF!_S2CL4*)ipZF2By2o2JnO1asV-+=ZfWqpIHD-%Hss)6rMu*CX< z!57+R4>tCU4i{UQQ{i}+JwOF zK^UskzasIAU0uzBODTOREVWKB1UT;ZO&MjZexY3!0}C!lbQ`?mKH|x%kF_4b=f4@& z_>BPG6PYvkd)ug1ULS(-BM&0`w@ZH(2KG8YUa$o@!*K|HC|M6sG|BH8%TpY@7JM#5 z2v%DtJ_!K4mI?SoJzj_cA8G?oh7dzs??*=akPr(1NM#}zp7*gV6m1Y0%!O$L9Qb>E zxKQvZEcpY zEX(9tna#B!Q+#zU_ogDAO=a9Ca*b!TGVH11pVPsxu!Hent-zdahPgcq^Ll}Zaegnu zd?4A!Fu#v+K_8I8vY?-Fen0Die%6H(I2KLdTslQ?^=zqi^Q1Q}klnphbKg3n0~_>@ zZZSHx)!^t>vt!$guWw8`v)B3TUdOZhTyGs>zI~YG{6Wt6LJI6%t zpHjPV!vFDU!D}bNo}LwXenH~S*@(O6ND*o@QI|Gv)o@v7tZtCqiSvj4ux{r$H4@4MQ+?_2)9@A^*}Q2Zz5T$Gwv zlA5AWo>`Ki;O^-gppc)Zkf`9Bn9QK~lZBCsp`Jm90SG`b#=t(Wp`L}gzO}8rjhTnP zrK68oK%BQlqOYA(M4Ur->a~W1s;*b z3=G^tAk28_ZrvZCAbW|YuPggiW^Qg~6A7WOaq$lGMz+)FO4`_Yn*X zjIy3Cjv*GOmrma6ci2Fr)!uoYVse?4dzY37;HcOU(q{XAXF$#5gbOns*B;*@cLiACah?`$rO zl8=|enc}X$K7ae-(T+tLeSbJ-U46y;z?b2S*yZvEpRSy@*jYcThS^`dQcLUYbTwd* OGkCiCxvXLW=UkO8ip# z1JfsDB(vT|`02rY@K zT9Qz;IJS0~f5W!y>iLQFE5cg0hqdj>Y+e@Gu_vZ$Z&~-+r2d1s6SkL5+)_SiTlTbL zIn$0-PT5v9b$jdNjdjy^7S29dI{$RbvQrJqFE%ef*S-As+-2*gEH`vp1cYv+4BQ&1WZXyEA{wxdmI!F4=l=@wRj8w(eQF{p8{u7uN4My>{ohIeQ;0 z+Iwr|o{OvYUEZ?i?ACoJcI-d4YyXkW2QO?qbZz^gvwM!5*>e2Ofn(?P9lx;s#GN&# zUhX+@Wyi_8`%YckeCEZz)3=VCy0-D$n>}amA3u9(-}#4IFTOi*?#i+AH%^?tdhWu- z!TUdHdY$S7+|Nzj^2WoxAsM-+OTN z{>zgOe_p-+`r7@MXCD8$`S9g~2M_K%e0u-k<2#REK6>=%($k+;o_@RYp#z4e|Yx#%e}Y1@4fqf|NZ|5@Bcq~|L^U)_YXh(fAsPH`}gl3 zfBgUP)8{W=z5>CwZ{L3W1cBebfB*ga_us#N|3?8v2q^y3)kxMCR@Sj140SG{uh=JoB!+%i; zj|~oO-2a8Nd^`+Tlssxzow%^UAd!V5;Drz8<7eCo%F<#%4GPPAmwL4CO1b#C!=t^0 zn@b~5g?;iex6D@sTw9;JIWFU8GbZ8({Xk{QrNlj4iWF>9@00FB>L_t(I%axHmYZOrw zhMzMtyOVX@O-K|ZVxt&TL<0VUfQ6!V7J?#(mH0<21raPIq_wcH5CoCLu*M?gHjxBG z1i#1{m38KvW3hL3XOju&feVMreV_B5_X_`5{-b^t((@2agMEX3M_PZn0`TJH^Bch8 ze&S|hiz71~W+pdCYd!i|8#R44-FkN~32zoJEL_}we6|Gn7m#^~PBCF!wzt=>Lb{X; zExL33^8HHv?MrXDbLBk;+Y7X&?&8@a(%Nevni>MkltV|4RRXm3fv-ECXdLLW(|bU( zzCk~0Gf}th2;k1j!)v3^@S;Kd9FaXG@-;-(aXZZC?`N27cHWEtYM2=ghyxPT0Dc1X z>%`1~_wZbkhN_!|Wn*Vos8{TEhUT@5e;_WJsIMMcG5%>DiS&dv_N`4@J0cnAQ-#>RjZ z00W5t&tJ^l-QC*ST1-p~00u^9XJ=AUl7oW-;2a+x2k__T=grN{+1c4XK0ZL~^z^i$ zp&>vEhr@4fZWb380S18T&!0cQ3IKpHF)?v=b_NIm0Q>vwY7D0baZ)n z31Fa5sELUQARIVaU0nqf0XzT+fB_63aA;@<$l~wse|mcA;^G1TmX?-)e)jkGPfkuA z92@|!<>h5S_4f8QP-JRq>d&7)^Yin8l7K8gED$&_FaV?gY+wLjpoW%~7NDe=nHfMG z5DO3j{R9kv5GbssrUpO)OyvVrlx>u0UKD0i;Dpm5S5dY16(DL5l{ixz|mhJU@&-OWCTb7_%}8-fE(P~+XIRO zJU|wp1|S>|J3KrLcz^+v1f&BDpd>&MAaibR4#5A_4(MucZwG9E1h4@u0P@C8;oo+g zIVj7kfJi{oV~E(NZ*h(@^-(Q(C`Psb3KZ{N;^GB(a8NE*Vwc715!9 zr-H4Ao|T_c6+VT_JH9H+P3>iXSt!a$F`>s`jn`w9GZ_~B!{0soaiV|O_c^R2aWa%}O3jUE)WO=pa zs~_Wz08z|ieY5A%$@FcBF9^!1a}m5ks@7gjn;67N>}S~Hrm`4sM5Hh`q7&5-N{|31 z6x1{ol7BnskoViZ0GqbLa#kW`Z)VCjt1MysKg|rT zi!?s##Ck>8c zpi|>$lGlw#@yMNi&V4`6OBGJ(H&7lqLlcTQ&1zWriG_fL>BnFcr~?;E93{M-xIozQ zO=EHQ#+?<}%@wbWWv23#!V70h9MOuUVaU>3kpTvYfc|LBw?&b*89~Gc9i&8tlT#kF ztpbZoAzkdB+UTy=tx%L3Z4)I{zY(Kb)eg{InobSJmNwPZt$14aS-uc4eKuY8h$dtfyxu^a%zA)>fYI&)@ZXky?^{5>xSC?;w4r&td6vBdi%vHm4=XJH!3yL3?Ep+T5aU_>i;yr_XGq zxZfCzUU@GvnoIk+_Nd`aky>S&H!b*{A%L>?*XPAgWL(Vf(k7qUS}>Zn=U(ZfcOc{B z3*tOHH@t5Ub5D~#N7!Fxx}P2)sy{vE_l(R7$aW&CX>c|&HY+7};vUIietK%}!phrCuh+;C@1usp;XLU<8Gq8P!rEI3ieg#W$!= zQcZr{hp>8sF?k&Yl0?B84OneiQxef-4TEFrq3O~JAZR}yEJHA|Xkqd49tR&8oq{zP zY@>J^HBV*(gJvJZc_0VFN7Sx?H7#75E3#?N8Z!C+_f53YU}pyggxx1?wQi5Yb-_`I`_V*SMx5+*P^b=ec5RON-k1cIlsBLk}(HiaJyab0`CI zo0{=1_LO$~oE2%Tl_}KURuX<`+mQN_sTdM&* zkFf!Xtl^e^gTy6ON=&gTn6)$JHQq2)33R@_!#9?BLNq-Wi{U|rVX7Vny$l6#+SZ@KvQt@VYb%<9JfapI^b9j=wa+Tqb4ei;8c5 z&1>Uz@lVFv6T4Z*YU$r4G`g=91lSeA<=GRZ!*KTWKDPR}NPUW%peCUj`Ix_LDq!8| zMH-V`Pv!a~QkTL||L@cqiTz)*G-0=ytr1KqTuFPan9y4gYD5>PleK`NZB$ev@W%t= zkp)_=lBUTLZJpAtZg;pjI;7r2y|26-N7&a(hX|`1YNM9N8{>8JAuv}hp1v`3JHT-=5lbXpbMq7X~2J5Kl zh7tyU`_AusMFZ{ej9D;Uyy;SQ!4nwgSnngsYBwdS&EO3NS*o04)*juAYl;57c2Ly0(DEZ8IY?zSph-kyxu+D`tt@oU{32J#I{vmy=#0ySPK zA+i(A3yl)qmTz*$dZi#y9FS;$;h%bY+;StNx{_R56Otq+?pGe^T^{5d7Gs&?`_r`8 zD&dzOA|j8@3A&FR5U3*eQNBf<4^4W_iS_()*8b4aaUzfk2 zzIcMWSEjm;EPZPk{j{1>oXd}pXAj!NaRm8{Sjz!D=~q3WJ@vmt6ND_?HI~|wUS1j5 z9!S1MKr7%nxoJ3k`GB^7yV~*{n~O~n6($~x5Bu{7s|JyXbAyKI4+tO(zZYMslK;Zc zzeHGVl{`iP@jfSKq>R;{+djJ9n%$%EL()Uw+sykjNQdflkJZSjqV_QDWivbZS~S{K zkE@T^Jcv)Dfm93!mf$XYnCT--_A$zo9MOkPB6&diM8MwOfV?+ApNv`moV@nqn>&lv zYbN1-M|jc~sG|yLN^1R2=`+1ih3jCshg`iP&mY$GMTcY^W^T`WOCX!{-KHmZ#GiRH zYl{|+KLn5!PCLtBy~9i}`#d^gCDDx$+GQb~uc;V#K3OgbbOG0j5{BRG-si%Bo{@lB zGIt+Ain8^C`!*S0d0OSWVO+Z89}}O8aFTZ>p&k}2gGCV zh#<$gswePFxWGT$4DC^8@84_e*^KT74?7n8!$8cg=sL$OlKr&HMh@Rr5%*Wr!xoOl zo7jItnj-xYgVTX)H1=A2bD(tleEH57#V{xAeW_ezISg5OC zg=k>hOLA^urTH_e6*vSYRqCm$J{xo}-x3@HH;bsHD1Z`Pzvsn}%cvfw%Q(}h`Dgtb z0_J^niUmoCM5$*f)6}}qi(u;cPgxfyeVaaVmOsG<)5`6tzU4wyhF;k|~|x>7-2hXpVBpc5k{L4M`Wbe6Q?tr^*B z`Y*>6*&R#~%JlBIitlZ^qGe3s21~h3U|&k%%jeMM;6!~UH|+0+<5V-_zDqZQN79?n?!Aj!Nj`YMO9?j>uqI9-Tex+nJD z%e0#Yca6(zqGUR|KITa?9x-#C0!JKJHO(+fy@1!B$%ZwJwncQW7vGYv?~!^`#L~Um zOL++>4qmqW`0Chc0T23G8|vO)tK=Z2`gvS4*qpqhIJCEv9i&&$09VO8YOz|oZ+ubd zNXVdLc&p=KsSgtmIPLN69P7xYkYQ1vJ?u1g)T!6Ru`k2wkdj*wDC)VryGu2=yb0?F z>q~~e>KZ0d_#7f3UgV%9MY1}vMgF{B8yfE{HL*pMyhYF)WDZ^^3vS8F zGlOhs%g_~pS3=WQ#494@jAXwOtr^Y|TnQ5zki>qRG)(oPY*f}U_=ip_{qB0!%w7~G zWE!P4p3khyW-JJnE>eECuYfI?^d366Shq!Wm#x&jAo>=HdCllE$>DPO0N;y#4G)D2y#B@5=N=+F%Xo2n{gKcPcK2!hP*^WSXl+ut; zyLvVoY>VL{H%Kd9^i~lsb8j4>$EllrparEOJNT?Ym>vJa$(P^tOG)5aVb_5w^*&M0 zYOJ`I`}9}UoSnYg#E(&yyK(tqr^@n}qU2H2DhkK-`2He% zgXr_4kpXoQHxAO9S`wEdmqGU4j=1JdG!OixdqB4PPP6RXA}>GM zumruUUH|ZG2$bBj)Qluj&uB=dRb)?^qomw?Z$X%#D+Q*O97eHrgVB2*mR$bFBU`*} zIem?dM)i}raTFDn@5^caxE^XFXVhBePmH9fqcTi`TLaXiueH=@06sl}>F%}h9H_e9 z>^O?LxM1EjX}NVppaO@NNQr=AtHcH-BU{yBT_vejJ#J)l^cl69Z7$sk`82Zyw7Wxt z=~J?hZm{f@W}|96FUJfy65Gk8?^{^yjhOahUMCNNpt5DJw}ZKH7b!bGiFY9y6OY&T z_N)?Jj(MuLTN36ZCJ6I5Xy7uVlrb$o*Z%=-)kPo9s?<^Yqz~!Z* z_mP8(unFq65XSi!$@YtieSQ!<7IEOaA9VkKI?lA`*(nURvfKL8cX}-+~uw9|_5)uC2`ZHcaeX7L8aG6Ghleg@F9aG%X$#g6^yP5apnB>YTz&EfS{q z9UVfSyEIczebC)qlVu5cOoMzS_jrC|)rQlAzK7sfiW0`M8mVIohazPE9Jzn*qPt%6 zZL8RELY@L09B83@Be;x5V-IHnn$}{RAT#<2JA%ttlk#^(%u}CGze|1JY5MPhbfnYG zIw%$XfBmA-<_pKLpGKwbRF$#P;@_)ech#>vj25sv25VM$ouo)?BXdRcO{)*OwTw)G zv43W~T6ekBMtUD%5Bm>`^Ltv!w4~65N!Ut5twl!Agrzyq4O2Fi3pUMtCU~>9gt_=h-f% z;1&OuSu?A_sJvIvQ+dZNo3?m1%b1+s&UAx?8sUHEe_sB7zkm4R%6)<@oYB_i5>3Ip zIA+?jVdX|zL{)?TGpx+=Ta>G80}0}Ax+722$XFNJsC1gcH56{8B)*)eU#r~HrC&}` z|EWW92&;6y;3}!L5zXa385@?-D%>dSvyK;?jqU2t_R3wvBW;$!j45uQ7tyEIQva;Db}r&bR3kqNSh)Q_$MJ#Uj3Gj1F;)sO|%6z#@<+ zi{pbYsYS#u`X$Nf($OS+lhw>xgjos1OnF^$-I$u;qhJswhH~p|ab*nO>zBrtb0ndn zxV0uh!LN`&xckTP+JW}gznSpU492)u+`f{9Yr)js`NmfYH#Wdtradc0TnKNz@Su!e zu$9}G_=ku;%4xk}eXl>)KgpuT>_<`Ud(A^a++K&pm3LbN;gI}ku@YVrA%FJBZ5$;m zobR8}OLtW4-i+qPPLS-(7<>M{)rhiPoi@?&vDeVq5%fmZk=mDdRV>Pb-l7pP1y6|J z8I>sF+TypKV=_^NwBU^>4JJq<*14GLfM2*XQzYdlqqjnE)gZsPW^E@mp&ww* zW9i>XL=uwLVZ9pO*8K>t>vdL~Ek_NUL$?LQi5sc#1Q-f6-ywKcIT8Kw?C(_3pbR`e|)%9S-({if|E+hR2W!&qfQ&UiF^I!|M#xhdWsenv^wpKCBiuxXbnp85`{i|;BM?Ba`lqTA zyRm=UWJl&E{8JzYDHFu>*Z10-?#A8D|5jW9Ho0*CAs0fAy~MqbwYuOq9jjt9*nuHI zbDwKvh)5Ir$r!fS5|;?Dt>V+@F*v8=TJJF)TdnC#Mk>+tGDGCw;A~^PC`gUt*<(|i zB{{g{`uFehu`$fm4)&k7`u{xIV)yvA(%5SxX9MS80p2EKnLtCZ>tlX>*Z6nd&6-Mv$5rHD*db;&IBK3KH&M<+ArlGXDRdX1VVO4)&R$f4NxXI>GBh zSv|h>5GDAI(4E`@F?EnW zS>#c&Gw6~_XL`qQG4bK`W*>hek4LX*efn6|_MY+rXkNyAuu?NxS%L7~9tD3cn7&p( zCtfqe6sjB&Q-Vs7BP5+%;#Gk};4xtwU!KY0XXbmkUy$kR9)!~?*v)qw00!+Yg^#H> zc#8*z6zZo>+(bud?K<*!QO4ehiTCK&PD4G&n)Tr9X_3r-we z?fI+}-G~Yn93gI6F{}Dw_SC*FLZ)5(85zp4%uubtD)J)UELLkvGk4#tw&Tussa)mTD$R2&O~{ zCI3>fr-!-b@EGRI%g0L8UU%%u_<;e9439JNV;4KSxd|78v+I+8^rmMf3f40Jb}wEszROD?xBZu>Ll3;sUIoNxDK3|j3*sam2tC@@e$ z^!;+AK>efeBJB%ALsQ{uFui)oDoq()2USi?n=6C3#eetz?wPswc={I<8x=(8lE4EIsUfyGNZ{|KYn1IR|=E==f z(;!A5(-2y^2xRFCSPqzHAZn5RCN_bp22T(KEtjA(rFZ%>a4@STrHZflxKoqe9Z4@^ zM*scx_y73?Q{vt6?~WEl?2q*;@8 z3M*&@%l)SQmXkcUm)d@GT2#JdzhfSAP9|n#C;$E8X|pwD!r#X?0P>0ZisQ~TNqupW z*lUY~+ikD`vQb?@SAWX#r*Y+;=_|oacL$2CL$^(mV}aKO77pg}O+-=T1oLBT5sL2i z42Qth2+0@C`c+*D0*5!qy26sis<9a7>LN2{z%Qj49t z=L@x`4$ALHb*3COHoT?5S_c(Hs}g!V>W^=6Q0}zaubkDn)(lTax0+!+%B}9Vqw6{H zvL|BRM`O<@;eVi1DzM!tXtBrA20Ce@^Jz|>%X-t`vi-%WweXCh_LhI#bUg2*pcP~R z*RuTUzBKLXO~~uMd&o$v3@d0shHfUjC6c539PE6rF&;Ufa(Rw@K1*m7?f5)t`MjH0 z)_V(cajV5Am>f!kWcI@5rE8t6$S>5M=k=aRZROH6fA^jJp~2NlR4;Q2>L$7F#RT#9 z>4@1RhWG`Khy>P2j1Yx^BBL{S`niMaxlSWV-JBU0-T9zZ%>7mR3l$~QV$({o0;jTI ze5=cN^!Bc2bT|BcojXp~K#2cM>OTe*cM{Kg-j*CkiW)EGQot^}s;cy8_1_@JA0Whq zlrNr+R;Efa+`6N)s5rH*|E)nYZ3uqkk2C(E7@A|3YI`ozP~9Lexx#*1(r8luq+YPk z{J}c$s` zPM35Fx(YWB3Z5IYnN+L_4|jaR(5iWJi2~l&xy}aU7kW?o-V*6Av2wyZTG!E2KSW2* zGRLQkQU;Oz##ie-Z4fI)WSRxn$(ZcD;TL+;^r=a4(G~H3ZhK$lSXZj?cvyY8%d9JM zzc3#pD^W_QnWy#rx#;c&N@sqHhrnHRmj#i;s%zLm6SE(n&BWpd&f7>XnjV}OlZntI70fq%8~9<7 zMYaw`E-rp49-oC1N_uZTo)Cu%RR2QWdHpzQIcNsoDp`3xfP+`gI?tVQZ4X={qU?(n zV>0ASES^Xuc;9JBji{)RnFL(Lez;8XbB1uWaMp@p?7xhXk6V#!6B@aP4Rz7-K%a>i z?fvf}va_DGUXlI#4--`A3qK7J?-HwnG7O~H2;zR~RLW)_^#La!=}+>KW#anZ{|^D3 B7G?kd literal 0 HcmV?d00001 diff --git a/dependency-check-gradle/img/glyphicons-halflings.png b/dependency-check-gradle/img/glyphicons-halflings.png new file mode 100644 index 0000000000000000000000000000000000000000..a9969993201f9cee63cf9f49217646347297b643 GIT binary patch literal 12799 zcma*OWmH^Ivn@*S;K3nSf_t!#;0f+&pm7Po8`nk}2q8f5;M%x$SdAkd9FAvlc$ zx660V9e3Ox@4WZ^?7jZ%QFGU-T~%||Ug4iK6bbQY@zBuF2$hxOw9wF=A)nUSxR_5@ zEX>HBryGrjyuOFFv$Y4<+|3H@gQfEqD<)+}a~mryD|1U9*I_FOG&F%+Ww{SJ-V2BR zjt<81Ek$}Yb*95D4RS0HCps|uLyovt;P05hchQb-u2bzLtmog&f2}1VlNhxXV);S9 zM2buBg~!q9PtF)&KGRgf3#z7B(hm5WlNClaCWFs!-P!4-u*u5+=+D|ZE9e`KvhTHT zJBnLwGM%!u&vlE%1ytJ=!xt~y_YkFLQb6bS!E+s8l7PiPGSt9xrmg?LV&&SL?J~cI zS(e9TF1?SGyh+M_p@o1dyWu7o7_6p;N6hO!;4~ z2B`I;y`;$ZdtBpvK5%oQ^p4eR2L)BH>B$FQeC*t)c`L71gXHPUa|vyu`Bnz)H$ZcXGve(}XvR!+*8a>BLV;+ryG1kt0=)ytl zNJxFUN{V7P?#|Cp85QTa@(*Q3%K-R(Pkv1N8YU*(d(Y}9?PQ(j;NzWoEVWRD-~H$=f>j9~PN^BM2okI(gY-&_&BCV6RP&I$FnSEM3d=0fCxbxA6~l>54-upTrw zYgX@%m>jsSGi`0cQt6b8cX~+02IghVlNblR7eI;0ps}mpWUcxty1yG56C5rh%ep(X z?)#2d?C<4t-KLc*EAn>>M8%HvC1TyBSoPNg(4id~H8JwO#I)Bf;N*y6ai6K9_bA`4 z_g9(-R;qyH&6I$`b42v|0V3Z8IXN*p*8g$gE98+JpXNY+jXxU0zsR^W$#V=KP z3AEFp@OL}WqwOfsV<)A^UTF4&HF1vQecz?LWE@p^Z2){=KEC_3Iopx_eS42>DeiDG zWMXGbYfG~W7C8s@@m<_?#Gqk;!&)_Key@^0xJxrJahv{B&{^!>TV7TEDZlP|$=ZCz zmX=ZWtt4QZKx**)lQQoW8y-XLiOQy#T`2t}p6l*S`68ojyH@UXJ-b~@tN`WpjF z%7%Yzv807gsO!v=!(2uR)16!&U5~VPrPHtGzUU?2w(b1Xchq}(5Ed^G|SD7IG+kvgyVksU) z(0R)SW1V(>&q2nM%Z!C9=;pTg!(8pPSc%H01urXmQI6Gi^dkYCYfu6b4^tW))b^U+ z$2K&iOgN_OU7n#GC2jgiXU{caO5hZt0(>k+c^(r><#m|#J^s?zA6pi;^#*rp&;aqL zRcZi0Q4HhVX3$ybclxo4FFJW*`IV`)Bj_L3rQe?5{wLJh168Ve1jZv+f1D}f0S$N= zm4i|9cEWz&C9~ZI3q*gwWH^<6sBWuphgy@S3Qy?MJiL>gwd|E<2h9-$3;gT9V~S6r z)cAcmE0KXOwDA5eJ02-75d~f?3;n7a9d_xPBJaO;Z)#@s7gk5$Qn(Fc^w@9c5W0zY z59is0?Mt^@Rolcn{4%)Ioat(kxQH6}hIykSA)zht=9F_W*D#<}N(k&&;k;&gKkWIL z0Of*sP=X(Uyu$Pw;?F@?j{}=>{aSHFcii#78FC^6JGrg-)!)MV4AKz>pXnhVgTgx8 z1&5Y=>|8RGA6++FrSy=__k_imx|z-EI@foKi>tK0Hq2LetjUotCgk2QFXaej!BWYL zJc{fv(&qA7UUJ|AXLc5z*_NW#yWzKtl(c8mEW{A>5Hj^gfZ^HC9lQNQ?RowXjmuCj4!!54Us1=hY z0{@-phvC}yls!PmA~_z>Y&n&IW9FQcj}9(OLO-t^NN$c0o}YksCUWt|DV(MJB%%Sr zdf}8!9ylU2TW!=T{?)g-ojAMKc>3pW;KiZ7f0;&g)k}K^#HBhE5ot)%oxq$*$W@b# zg4p<Ou`ME|Kd1WHK@8 zzLD+0(NHWa`B{em3Ye?@aVsEi>y#0XVZfaFuq#;X5C3{*ikRx7UY4FF{ZtNHNO?A_ z#Q?hwRv~D8fPEc%B5E-ZMI&TAmikl||EERumQCRh7p;)>fdZMxvKq;ky0}7IjhJph zW*uuu*(Y6)S;Od--8uR^R#sb$cmFCnPcj9PPCWhPN;n`i1Q#Qn>ii z{WR|0>8F`vf&#E(c2NsoH=I7Cd-FV|%(7a`i}gZw4N~QFFG2WtS^H%@c?%9UZ+kez z;PwGgg_r6V>Kn5n(nZ40P4qMyrCP3bDkJp@hp6&X3>gzC>=f@Hsen<%I~7W+x@}b> z0}Et*vx_50-q@PIV=(3&Tbm}}QRo*FP2@)A#XX-8jYspIhah`9ukPBr)$8>Tmtg&R z?JBoH17?+1@Y@r>anoKPQ}F8o9?vhcG79Cjv^V6ct709VOQwg{c0Q#rBSsSmK3Q;O zBpNihl3S0_IGVE)^`#94#j~$;7+u870yWiV$@={|GrBmuz4b)*bCOPkaN0{6$MvazOEBxFdKZDlbVvv{8_*kJ zfE6C`4&Kkz<5u%dEdStd85-5UHG5IOWbo8i9azgg#zw-(P1AA049hddAB*UdG3Vn0 zX`OgM+EM|<+KhJ<=k?z~WA5waVj?T9eBdfJGebVifBKS1u<$#vl^BvSg)xsnT5Aw_ZY#}v*LXO#htB>f}x3qDdDHoFeb zAq7;0CW;XJ`d&G*9V)@H&739DpfWYzdQt+Kx_E1K#Cg1EMtFa8eQRk_JuUdHD*2;W zR~XFnl!L2A?48O;_iqCVr1oxEXvOIiN_9CUVTZs3C~P+11}ebyTRLACiJuMIG#`xP zKlC|E(S@QvN+%pBc6vPiQS8KgQAUh75C0a2xcPQDD$}*bM&z~g8+=9ltmkT$;c;s z5_=8%i0H^fEAOQbHXf0;?DN5z-5+1 zDxj50yYkz4ox9p$HbZ|H?8ukAbLE^P$@h}L%i6QVcY>)i!w=hkv2zvrduut%!8>6b zcus3bh1w~L804EZ*s96?GB&F7c5?m?|t$-tp2rKMy>F*=4;w*jW}^;8v`st&8)c; z2Ct2{)?S(Z;@_mjAEjb8x=qAQvx=}S6l9?~H?PmP`-xu;ME*B8sm|!h@BX4>u(xg_ zIHmQzp4Tgf*J}Y=8STR5_s)GKcmgV!$JKTg@LO402{{Wrg>#D4-L%vjmtJ4r?p&$F!o-BOf7ej~ z6)BuK^^g1b#(E>$s`t3i13{6-mmSp7{;QkeG5v}GAN&lM2lQT$@(aQCcFP(%UyZbF z#$HLTqGT^@F#A29b0HqiJsRJAlh8kngU`BDI6 zJUE~&!cQ*&f95Ot$#mxU5+*^$qg_DWNdfu+1irglB7yDglzH()2!@#rpu)^3S8weW z_FE$=j^GTY*|5SH95O8o8W9FluYwB=2PwtbW|JG6kcV^dMVmX(wG+Otj;E$%gfu^K z!t~<3??8=()WQSycsBKy24>NjRtuZ>zxJIED;YXaUz$@0z4rl+TW zWxmvM$%4jYIpO>j5k1t1&}1VKM~s!eLsCVQ`TTjn3JRXZD~>GM z$-IT~(Y)flNqDkC%DfbxaV9?QuWCV&-U1yzrV@0jRhE;)ZO0=r-{s@W?HOFbRHDDV zq;eLo+wOW;nI|#mNf(J?RImB9{YSO2Y`9825Lz#u4(nk3)RGv3X8B(A$TsontJ8L! z9JP^eWxtKC?G8^xAZa1HECx*rp35s!^%;&@Jyk)NexVc)@U4$^X1Dag6`WKs|(HhZ#rzO2KEw3xh~-0<;|zcs0L>OcO#YYX{SN8m6`9pp+ zQG@q$I)T?aoe#AoR@%om_#z=c@ych!bj~lV13Qi-xg$i$hXEAB#l=t7QWENGbma4L zbBf*X*4oNYZUd_;1{Ln_ZeAwQv4z?n9$eoxJeI?lU9^!AB2Y~AwOSq67dT9ADZ)s@ zCRYS7W$Zpkdx$3T>7$I%3EI2ik~m!f7&$Djpt6kZqDWZJ-G{*_eXs*B8$1R4+I}Kf zqniwCI64r;>h2Lu{0c(#Atn)%E8&)=0S4BMhq9$`vu|Ct;^ur~gL`bD>J@l)P$q_A zO7b3HGOUG`vgH{}&&AgrFy%K^>? z>wf**coZ2vdSDcNYSm~dZ(vk6&m6bVKmVgrx-X<>{QzA!)2*L+HLTQz$e8UcB&Djq zl)-%s$ZtUN-R!4ZiG=L0#_P=BbUyH+YPmFl_ogkkQ$=s@T1v}rNnZ^eMaqJ|quc+6 z*ygceDOrldsL30w`H;rNu+IjlS+G~p&0SawXCA1+D zC%cZtjUkLNq%FadtHE?O(yQTP486A{1x<{krq#rpauNQaeyhM3*i0%tBpQHQo-u)x z{0{&KS`>}vf2_}b160XZO2$b)cyrHq7ZSeiSbRvaxnKUH{Q`-P(nL&^fcF2){vhN- zbX&WEjP7?b4A%0y6n_=m%l00uZ+}mCYO(!x?j$+O$*TqoD_Q5EoyDJ?w?^UIa491H zE}87(bR`X;@u#3Qy~9wWdWQIg1`cXrk$x9=ccR|RY1~%{fAJ@uq@J3e872x0v$hmv ze_KcL(wM|n0EOp;t{hKoohYyDmYO;!`7^Lx;0k=PWPGZpI>V5qYlzjSL_(%|mud50 z7#{p97s`U|Sn$WYF>-i{i4`kzlrV6a<}=72q2sAT7Zh{>P%*6B;Zl;~0xWymt10Mo zl5{bmR(wJefJpNGK=fSRP|mpCI-)Nf6?Pv==FcFmpSwF1%CTOucV{yqxSyx4Zws3O z8hr5Uyd%ezIO7?PnEO0T%af#KOiXD$e?V&OX-B|ZX-YsgSs%sv-6U+sLPuz{D4bq| zpd&|o5tNCmpT>(uIbRf?8c}d3IpOb3sn6>_dr*26R#ev<_~vi)wleW$PX|5)$_ z+_|=pi(0D(AB_sjQ;sQQSM&AWqzDO1@NHw;C9cPdXRKRI#@nUW)CgFxzQ1nyd!+h& zcjU!U=&u|>@}R(9D$%lu2TlV>@I2-n@fCr5PrZNVyKWR7hm zWjoy^p7v8m#$qN0K#8jT- zq`mSirDZDa1Jxm;Rg3rAPhC)LcI4@-RvKT+@9&KsR3b0_0zuM!Fg7u>oF>3bzOxZPU&$ab$Z9@ zY)f7pKh22I7ZykL{YsdjcqeN++=0a}elQM-4;Q)(`Ep3|VFHqnXOh14`!Bus& z9w%*EWK6AiAM{s$6~SEQS;A>ey$#`7)khZvamem{P?>k)5&7Sl&&NXKk}o!%vd;-! zpo2p-_h^b$DNBO>{h4JdGB=D>fvGIYN8v&XsfxU~VaefL?q} z3ekM?iOKkCzQHkBkhg=hD!@&(L}FcHKoa zbZ7)H1C|lHjwEb@tu=n^OvdHOo7o+W`0-y3KdP#bb~wM=Vr_gyoEq|#B?$&d$tals ziIs-&7isBpvS|CjC|7C&3I0SE?~`a%g~$PI%;au^cUp@ER3?mn-|vyu!$7MV6(uvt z+CcGuM(Ku2&G0tcRCo7#D$Dirfqef2qPOE5I)oCGzmR5G!o#Q~(k~)c=LpIfrhHQk zeAva6MilEifE7rgP1M7AyWmLOXK}i8?=z2;N=no)`IGm#y%aGE>-FN zyXCp0Sln{IsfOBuCdE*#@CQof%jzuU*jkR*Su3?5t}F(#g0BD0Zzu|1MDes8U7f9; z$JBg|mqTXt`muZ8=Z`3wx$uizZG_7>GI7tcfOHW`C2bKxNOR)XAwRkLOaHS4xwlH4 zDpU29#6wLXI;H?0Se`SRa&I_QmI{zo7p%uveBZ0KZKd9H6@U?YGArbfm)D*^5=&Rp z`k{35?Z5GbZnv>z@NmJ%+sx=1WanWg)8r}C_>EGR8mk(NR$pW<-l8OTU^_u3M@gwS z7}GGa1)`z5G|DZirw;FB@VhH7Dq*0qc=|9lLe{w2#`g+_nt>_%o<~9(VZe=zI*SSz4w43-_o>4E4`M@NPKTWZuQJs)?KXbWp1M zimd5F;?AP(LWcaI-^Sl{`~>tmxsQB9Y$Xi*{Zr#py_+I$vx7@NY`S?HFfS!hUiz$a z{>!&e1(16T!Om)m)&k1W#*d#GslD^4!TwiF2WjFBvi=Ms!ADT)ArEW6zfVuIXcXVk z>AHjPADW+mJzY`_Ieq(s?jbk4iD2Rb8*V3t6?I+E06(K8H!!xnDzO%GB;Z$N-{M|B zeT`jo%9)s%op*XZKDd6*)-^lWO{#RaIGFdBH+;XXjI(8RxpBc~azG1H^2v7c^bkFE zZCVPE+E*Q=FSe8Vm&6|^3ki{9~qafiMAf7i4APZg>b%&5>nT@pHH z%O*pOv(77?ZiT{W zBibx}Q12tRc7Py1NcZTp`Q4ey%T_nj@1WKg5Fz_Rjl4wlJQj)rtp8yL3r!Shy zvZvnmh!tH4T6Js-?vI0<-rzzl{mgT*S0d_7^AU_8gBg^03o-J=p(1o6kww2hx|!%T z-jqp}m^G*W?$!R#M%Ef?&2jYxmx+lXWZszpI4d$pUN`(S)|*c^CgdwY>Fa>> zgGBJhwe8y#Xd*q0=@SLEgPF>+Qe4?%E*v{a`||luZ~&dqMBrRfJ{SDMaJ!s_;cSJp zSqZHXIdc@@XteNySUZs^9SG7xK`8=NBNM)fRVOjw)D^)w%L2OPkTQ$Tel-J)GD3=YXy+F4in(ILy*A3m@3o73uv?JC}Q>f zrY&8SWmesiba0|3X-jmlMT3 z*ST|_U@O=i*sM_*48G)dgXqlwoFp5G6qSM3&%_f_*n!PiT>?cNI)fAUkA{qWnqdMi+aNK_yVQ&lx4UZknAc9FIzVk% zo6JmFH~c{_tK!gt4+o2>)zoP{sR}!!vfRjI=13!z5}ijMFQ4a4?QIg-BE4T6!#%?d&L;`j5=a`4is>U;%@Rd~ zXC~H7eGQhhYWhMPWf9znDbYIgwud(6$W3e>$W4$~d%qoJ z+JE`1g$qJ%>b|z*xCKenmpV$0pM=Gl-Y*LT8K+P)2X#;XYEFF4mRbc~jj?DM@(1e`nL=F4Syv)TKIePQUz)bZ?Bi3@G@HO$Aps1DvDGkYF50O$_welu^cL7;vPiMGho74$;4fDqKbE{U zd1h{;LfM#Fb|Z&uH~Rm_J)R~Vy4b;1?tW_A)Iz#S_=F|~pISaVkCnQ0&u%Yz%o#|! zS-TSg87LUfFSs{tTuM3$!06ZzH&MFtG)X-l7>3)V?Txuj2HyG*5u;EY2_5vU0ujA? zHXh5G%6e3y7v?AjhyX79pnRBVr}RmPmtrxoB7lkxEzChX^(vKd+sLh?SBic=Q)5nA zdz7Mw3_iA>;T^_Kl~?1|5t%GZ;ki_+i>Q~Q1EVdKZ)$Sh3LM@ea&D~{2HOG++7*wF zAC6jW4>fa~!Vp5+$Z{<)Qxb|{unMgCv2)@%3j=7)Zc%U<^i|SAF88s!A^+Xs!OASYT%7;Jx?olg_6NFP1475N z#0s<@E~FI}#LNQ{?B1;t+N$2k*`K$Hxb%#8tRQi*Z#No0J}Pl;HWb){l7{A8(pu#@ zfE-OTvEreoz1+p`9sUI%Y{e5L-oTP_^NkgpYhZjp&ykinnW;(fu1;ttpSsgYM8ABX4dHe_HxU+%M(D=~) zYM}XUJ5guZ;=_ZcOsC`_{CiU$zN3$+x&5C`vX-V3`8&RjlBs^rf00MNYZW+jCd~7N z%{jJuUUwY(M`8$`B>K&_48!Li682ZaRknMgQ3~dnlp8C?__!P2z@=Auv;T^$yrsNy zCARmaA@^Yo2sS%2$`031-+h9KMZsIHfB>s@}>Y(z988e!`%4=EDoAQ0kbk>+lCoK60Mx9P!~I zlq~wf7kcm_NFImt3ZYlE(b3O1K^QWiFb$V^a2Jlwvm(!XYx<`i@ZMS3UwFt{;x+-v zhx{m=m;4dgvkKp5{*lfSN3o^keSpp9{hlXj%=}e_7Ou{Yiw(J@NXuh*;pL6@$HsfB zh?v+r^cp@jQ4EspC#RqpwPY(}_SS$wZ{S959`C25777&sgtNh%XTCo9VHJC-G z;;wi9{-iv+ETiY;K9qvlEc04f;ZnUP>cUL_T*ms``EtGoP^B#Q>n2dSrbAg8a>*Lg zd0EJ^=tdW~7fbcLFsqryFEcy*-8!?;n%;F+8i{eZyCDaiYxghr z$8k>L|2&-!lhvuVdk!r-kpSFl`5F5d4DJr%M4-qOy3gdmQbqF1=aBtRM7)c_Ae?$b8 zQg4c8*KQ{XJmL)1c7#0Yn0#PTMEs4-IHPjkn0!=;JdhMXqzMLeh`yOylXROP- zl#z3+fwM9l3%VN(6R77ua*uI9%hO7l7{+Hcbr(peh;afUK?B4EC09J{-u{mv)+u#? zdKVBCPt`eU@IzL)OXA`Ebu`Xp?u0m%h&X41}FNfnJ*g1!1wcbbpo%F4x!-#R9ft!8{5`Ho}04?FI#Kg zL|k`tF1t_`ywdy8(wnTut>HND(qNnq%Sq=AvvZbXnLx|mJhi!*&lwG2g|edBdVgLy zjvVTKHAx(+&P;P#2Xobo7_RttUi)Nllc}}hX>|N?-u5g7VJ-NNdwYcaOG?NK=5)}` zMtOL;o|i0mSKm(UI_7BL_^6HnVOTkuPI6y@ZLR(H?c1cr-_ouSLp{5!bx^DiKd*Yb z{K78Ci&Twup zTKm)ioN|wcYy%Qnwb)IzbH>W!;Ah5Zdm_jRY`+VRJ2 zhkspZ9hbK3iQD91A$d!0*-1i#%x81|s+SPRmD}d~<1p6!A13(!vABP2kNgqEG z?AMgl^P+iRoIY(9@_I?n1829lGvAsRnHwS~|5vD2+Zi53j<5N4wNn0{q>>jF9*bI) zL$kMXM-awNOElF>{?Jr^tOz1glbwaD-M0OKOlTeW3C!1ZyxRbB>8JDof(O&R1bh%3x#>y2~<>OXO#IIedH0Q`(&&?eo-c~ z>*Ah#3~09unym~UC-UFqqI>{dmUD$Y4@evG#ORLI*{ZM)Jl=e1it!XzY($S3V zLG!Y6fCjE>x6r@5FG1n|8ompSZaJ>9)q6jqU;XxCQk9zV(?C9+i*>w z21+KYt1gXX&0`x3E)hS7I5}snbBzox9C@Xzcr|{B8Hw;SY1$}&BoYKXH^hpjW-RgJ z-Fb}tannKCv>y~^`r|(1Q9;+sZlYf3XPSX|^gR01UFtu$B*R;$sPZdIZShRr>|b@J z;#G{EdoY+O;REEjQ}X7_YzWLO+Ey3>a_KDe1CjSe| z6arqcEZ)CX!8r(si`dqbF$uu&pnf^Np{1f*TdJ`r2;@SaZ z#hb4xlaCA@Pwqj#LlUEe5L{I$k(Zj$d3(~)u(F%&xb8={N9hKxlZIO1ABsM{Mt|)2 zJ^t9Id;?%4PfR4&Ph9B9cFK~@tG3wlFW-0fXZS_L4U*EiAA%+`h%q2^6BCC;t0iO4V=s4Qug{M|iDV@s zC7|ef-dxiR7T&Mpre!%hiUhHM%3Qxi$Lzw6&(Tvlx9QA_7LhYq<(o~=Y>3ka-zrQa zhGpfFK@)#)rtfz61w35^sN1=IFw&Oc!Nah+8@qhJ0UEGr;JplaxOGI82OVqZHsqfX ze1}r{jy;G?&}Da}a7>SCDsFDuzuseeCKof|Dz2BPsP8? zY;a)Tkr2P~0^2BeO?wnzF_Ul-ekY=-w26VnU%U3f19Z-pj&2 z4J_a|o4Dci+MO)mPQIM>kdPG1xydiR9@#8m zh27D7GF{p|a{8({Q-Pr-;#jV{2zHR>lGoFtIfIpoMo?exuQyX_A;;l0AP4!)JEM$EwMInZkj+8*IHP4vKRd zKx_l-i*>A*C@{u%ct`y~s6MWAfO{@FPIX&sg8H{GMDc{4M3%$@c8&RAlw0-R<4DO3 trJqdc$mBpWeznn?E0M$F`|3v=`3%T2A17h;rxP7$%JLd=6(2u;`(N3pt&so# literal 0 HcmV?d00001 diff --git a/dependency-check-gradle/index.html b/dependency-check-gradle/index.html new file mode 100644 index 000000000..22e290f4d --- /dev/null +++ b/dependency-check-gradle/index.html @@ -0,0 +1,167 @@ + + + + + + + + + dependency-check-gradle - Dependency-Check Gradle Plugin + + + + + + + + + + + + + + + + + + + + + Fork me on GitHub + + + + + +
    + + + + + +
    +
    + +
    + + +
    + +

    Dependency-Check Gradle Plugin

    +

    Dependency-Check is a utility that identifies project dependencies and checks if there are any known, publicly disclosed, vulnerabilities. This tool can be part of the solution to the OWASP Top 10 2013: A9 - Using Components with Known Vulnerabilities.

    +

    The Gradle Plugin is still a work in progress. The core dependency-check functionality works; however, the configuration options available in the other plugins still need to be completed. For more information about the plugin, including usage, please see the github repo’s readme.

    + +
    +

    License

    +

    Permission to modify and redistribute is granted under the terms of the Apache 2.0 license. See the LICENSE.txt file for the full license.

    +

    Dependency-Check makes use of several other open source libraries. Please see the NOTICE.txt file for more information.

    +
    +
    +
    + +
    + +
    +
    +
    +

    Copyright © 2015 + OWASP. + All rights reserved. + +

    +
    + + + +
    +
    + + diff --git a/dependency-check-gradle/issue-tracking.html b/dependency-check-gradle/issue-tracking.html new file mode 100644 index 000000000..c954e7e40 --- /dev/null +++ b/dependency-check-gradle/issue-tracking.html @@ -0,0 +1,206 @@ + + + + + + + + + dependency-check-gradle - Issue Tracking + + + + + + + + + + + + + + + + + + + + + Fork me on GitHub + + + + + +
    + + + + + +
    +
    + +
    + + +
    + +
    +

    Overview

    +

    This project uses github to manage its issues.

    +
    +

    Issue Tracking

    +

    Issues, bugs, and feature requests should be submitted to the following issue tracking system for this project.

    +
    +
    +
    +
    + +
    + +
    +
    +
    +

    Copyright © 2015 + OWASP. + All rights reserved. + +

    +
    + + + +
    +
    + + diff --git a/dependency-check-gradle/js/apache-maven-fluido-1.3.1.min.js b/dependency-check-gradle/js/apache-maven-fluido-1.3.1.min.js new file mode 100644 index 000000000..d16bb7789 --- /dev/null +++ b/dependency-check-gradle/js/apache-maven-fluido-1.3.1.min.js @@ -0,0 +1,21 @@ +/*! + * jQuery JavaScript Library v1.9.1 + * http://jquery.com/ + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * + * Copyright 2005, 2012 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2013-2-4 + */ +(function(a3,aH){var aj,x,aD=typeof aH,l=a3.document,aM=a3.location,bj=a3.jQuery,I=a3.$,ab={},a7=[],t="1.9.1",aJ=a7.concat,ap=a7.push,a5=a7.slice,aN=a7.indexOf,A=ab.toString,W=ab.hasOwnProperty,aR=t.trim,bK=function(e,b4){return new bK.fn.init(e,b4,x)},bB=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,ad=/\S+/g,D=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,bs=/^(?:(<[\w\W]+>)[^>]*|#([\w-]*))$/,a=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,bi=/^[\],:{}\s]*$/,bl=/(?:^|:|,)(?:\s*\[)+/g,bH=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,a0=/"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,bT=/^-ms-/,aW=/-([\da-z])/gi,N=function(e,b4){return b4.toUpperCase()},bX=function(e){if(l.addEventListener||e.type==="load"||l.readyState==="complete"){bm();bK.ready()}},bm=function(){if(l.addEventListener){l.removeEventListener("DOMContentLoaded",bX,false);a3.removeEventListener("load",bX,false)}else{l.detachEvent("onreadystatechange",bX);a3.detachEvent("onload",bX)}};bK.fn=bK.prototype={jquery:t,constructor:bK,init:function(e,b6,b5){var b4,b7;if(!e){return this}if(typeof e==="string"){if(e.charAt(0)==="<"&&e.charAt(e.length-1)===">"&&e.length>=3){b4=[null,e,null]}else{b4=bs.exec(e)}if(b4&&(b4[1]||!b6)){if(b4[1]){b6=b6 instanceof bK?b6[0]:b6;bK.merge(this,bK.parseHTML(b4[1],b6&&b6.nodeType?b6.ownerDocument||b6:l,true));if(a.test(b4[1])&&bK.isPlainObject(b6)){for(b4 in b6){if(bK.isFunction(this[b4])){this[b4](b6[b4])}else{this.attr(b4,b6[b4])}}}return this}else{b7=l.getElementById(b4[2]);if(b7&&b7.parentNode){if(b7.id!==b4[2]){return b5.find(e)}this.length=1;this[0]=b7}this.context=l;this.selector=e;return this}}else{if(!b6||b6.jquery){return(b6||b5).find(e)}else{return this.constructor(b6).find(e)}}}else{if(e.nodeType){this.context=this[0]=e;this.length=1;return this}else{if(bK.isFunction(e)){return b5.ready(e)}}}if(e.selector!==aH){this.selector=e.selector;this.context=e.context}return bK.makeArray(e,this)},selector:"",length:0,size:function(){return this.length},toArray:function(){return a5.call(this)},get:function(e){return e==null?this.toArray():(e<0?this[this.length+e]:this[e])},pushStack:function(e){var b4=bK.merge(this.constructor(),e);b4.prevObject=this;b4.context=this.context;return b4},each:function(b4,e){return bK.each(this,b4,e)},ready:function(e){bK.ready.promise().done(e);return this},slice:function(){return this.pushStack(a5.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(b5){var e=this.length,b4=+b5+(b5<0?e:0);return this.pushStack(b4>=0&&b40){return}aj.resolveWith(l,[bK]);if(bK.fn.trigger){bK(l).trigger("ready").off("ready")}},isFunction:function(e){return bK.type(e)==="function"},isArray:Array.isArray||function(e){return bK.type(e)==="array"},isWindow:function(e){return e!=null&&e==e.window},isNumeric:function(e){return !isNaN(parseFloat(e))&&isFinite(e)},type:function(e){if(e==null){return String(e)}return typeof e==="object"||typeof e==="function"?ab[A.call(e)]||"object":typeof e},isPlainObject:function(b6){if(!b6||bK.type(b6)!=="object"||b6.nodeType||bK.isWindow(b6)){return false}try{if(b6.constructor&&!W.call(b6,"constructor")&&!W.call(b6.constructor.prototype,"isPrototypeOf")){return false}}catch(b5){return false}var b4;for(b4 in b6){}return b4===aH||W.call(b6,b4)},isEmptyObject:function(b4){var e;for(e in b4){return false}return true},error:function(e){throw new Error(e)},parseHTML:function(b7,b5,b6){if(!b7||typeof b7!=="string"){return null}if(typeof b5==="boolean"){b6=b5;b5=false}b5=b5||l;var b4=a.exec(b7),e=!b6&&[];if(b4){return[b5.createElement(b4[1])]}b4=bK.buildFragment([b7],b5,e);if(e){bK(e).remove()}return bK.merge([],b4.childNodes)},parseJSON:function(e){if(a3.JSON&&a3.JSON.parse){return a3.JSON.parse(e)}if(e===null){return e}if(typeof e==="string"){e=bK.trim(e);if(e){if(bi.test(e.replace(bH,"@").replace(a0,"]").replace(bl,""))){return(new Function("return "+e))()}}}bK.error("Invalid JSON: "+e)},parseXML:function(b6){var b4,b5;if(!b6||typeof b6!=="string"){return null}try{if(a3.DOMParser){b5=new DOMParser();b4=b5.parseFromString(b6,"text/xml")}else{b4=new ActiveXObject("Microsoft.XMLDOM");b4.async="false";b4.loadXML(b6)}}catch(b7){b4=aH}if(!b4||!b4.documentElement||b4.getElementsByTagName("parsererror").length){bK.error("Invalid XML: "+b6)}return b4},noop:function(){},globalEval:function(e){if(e&&bK.trim(e)){(a3.execScript||function(b4){a3["eval"].call(a3,b4)})(e)}},camelCase:function(e){return e.replace(bT,"ms-").replace(aW,N)},nodeName:function(b4,e){return b4.nodeName&&b4.nodeName.toLowerCase()===e.toLowerCase()},each:function(b8,b9,b4){var b7,b5=0,b6=b8.length,e=ac(b8);if(b4){if(e){for(;b50&&(b4-1) in b5)}x=bK(l);var bZ={};function af(b4){var e=bZ[b4]={};bK.each(b4.match(ad)||[],function(b6,b5){e[b5]=true});return e}bK.Callbacks=function(cd){cd=typeof cd==="string"?(bZ[cd]||af(cd)):bK.extend({},cd);var b7,b6,e,b8,b9,b5,ca=[],cb=!cd.once&&[],b4=function(ce){b6=cd.memory&&ce;e=true;b9=b5||0;b5=0;b8=ca.length;b7=true;for(;ca&&b9-1){ca.splice(cf,1);if(b7){if(cf<=b8){b8--}if(cf<=b9){b9--}}}})}return this},has:function(ce){return ce?bK.inArray(ce,ca)>-1:!!(ca&&ca.length)},empty:function(){ca=[];return this},disable:function(){ca=cb=b6=aH;return this},disabled:function(){return !ca},lock:function(){cb=aH;if(!b6){cc.disable()}return this},locked:function(){return !cb},fireWith:function(cf,ce){ce=ce||[];ce=[cf,ce.slice?ce.slice():ce];if(ca&&(!e||cb)){if(b7){cb.push(ce)}else{b4(ce)}}return this},fire:function(){cc.fireWith(this,arguments);return this},fired:function(){return !!e}};return cc};bK.extend({Deferred:function(b5){var b4=[["resolve","done",bK.Callbacks("once memory"),"resolved"],["reject","fail",bK.Callbacks("once memory"),"rejected"],["notify","progress",bK.Callbacks("memory")]],b6="pending",b7={state:function(){return b6},always:function(){e.done(arguments).fail(arguments);return this},then:function(){var b8=arguments;return bK.Deferred(function(b9){bK.each(b4,function(cb,ca){var cd=ca[0],cc=bK.isFunction(b8[cb])&&b8[cb];e[ca[1]](function(){var ce=cc&&cc.apply(this,arguments);if(ce&&bK.isFunction(ce.promise)){ce.promise().done(b9.resolve).fail(b9.reject).progress(b9.notify)}else{b9[cd+"With"](this===b7?b9.promise():this,cc?[ce]:arguments)}})});b8=null}).promise()},promise:function(b8){return b8!=null?bK.extend(b8,b7):b7}},e={};b7.pipe=b7.then;bK.each(b4,function(b9,b8){var cb=b8[2],ca=b8[3];b7[b8[1]]=cb.add;if(ca){cb.add(function(){b6=ca},b4[b9^1][2].disable,b4[2][2].lock)}e[b8[0]]=function(){e[b8[0]+"With"](this===e?b7:this,arguments);return this};e[b8[0]+"With"]=cb.fireWith});b7.promise(e);if(b5){b5.call(e,e)}return e},when:function(b7){var b5=0,b9=a5.call(arguments),e=b9.length,b4=e!==1||(b7&&bK.isFunction(b7.promise))?e:0,cc=b4===1?b7:bK.Deferred(),b6=function(ce,cf,cd){return function(cg){cf[ce]=this;cd[ce]=arguments.length>1?a5.call(arguments):cg;if(cd===cb){cc.notifyWith(cf,cd)}else{if(!(--b4)){cc.resolveWith(cf,cd)}}}},cb,b8,ca;if(e>1){cb=new Array(e);b8=new Array(e);ca=new Array(e);for(;b5
    org.owasp.dependencycheck.data.update
    + org.owasp.dependencycheck.data.update.cpe +
    @@ -100,12 +105,7 @@
    - org.owasp.dependencycheck.data.update.task -
    - org.owasp.dependencycheck.data.update.xml + org.owasp.dependencycheck.data.update.nvd
    a";ce=b4.getElementsByTagName("*");cc=b4.getElementsByTagName("a")[0];if(!ce||!cc||!ce.length){return{}}cd=l.createElement("select");b6=cd.appendChild(l.createElement("option"));cb=b4.getElementsByTagName("input")[0];cc.style.cssText="top:1px;float:left;opacity:.5";cf={getSetAttribute:b4.className!=="t",leadingWhitespace:b4.firstChild.nodeType===3,tbody:!b4.getElementsByTagName("tbody").length,htmlSerialize:!!b4.getElementsByTagName("link").length,style:/top/.test(cc.getAttribute("style")),hrefNormalized:cc.getAttribute("href")==="/a",opacity:/^0.5/.test(cc.style.opacity),cssFloat:!!cc.style.cssFloat,checkOn:!!cb.value,optSelected:b6.selected,enctype:!!l.createElement("form").enctype,html5Clone:l.createElement("nav").cloneNode(true).outerHTML!=="<:nav>",boxModel:l.compatMode==="CSS1Compat",deleteExpando:true,noCloneEvent:true,inlineBlockNeedsLayout:false,shrinkWrapBlocks:false,reliableMarginRight:true,boxSizingReliable:true,pixelPosition:false};cb.checked=true;cf.noCloneChecked=cb.cloneNode(true).checked;cd.disabled=true;cf.optDisabled=!b6.disabled;try{delete b4.test}catch(b9){cf.deleteExpando=false}cb=l.createElement("input");cb.setAttribute("value","");cf.input=cb.getAttribute("value")==="";cb.value="t";cb.setAttribute("type","radio");cf.radioValue=cb.value==="t";cb.setAttribute("checked","t");cb.setAttribute("name","t");ca=l.createDocumentFragment();ca.appendChild(cb);cf.appendChecked=cb.checked;cf.checkClone=ca.cloneNode(true).cloneNode(true).lastChild.checked;if(b4.attachEvent){b4.attachEvent("onclick",function(){cf.noCloneEvent=false});b4.cloneNode(true).click()}for(b7 in {submit:true,change:true,focusin:true}){b4.setAttribute(b8="on"+b7,"t");cf[b7+"Bubbles"]=b8 in a3||b4.attributes[b8].expando===false}b4.style.backgroundClip="content-box";b4.cloneNode(true).style.backgroundClip="";cf.clearCloneStyle=b4.style.backgroundClip==="content-box";bK(function(){var cg,cj,ci,ch="padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",e=l.getElementsByTagName("body")[0];if(!e){return}cg=l.createElement("div");cg.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px";e.appendChild(cg).appendChild(b4);b4.innerHTML="
    t
    ";ci=b4.getElementsByTagName("td");ci[0].style.cssText="padding:0;margin:0;border:0;display:none";b5=(ci[0].offsetHeight===0);ci[0].style.display="";ci[1].style.display="none";cf.reliableHiddenOffsets=b5&&(ci[0].offsetHeight===0);b4.innerHTML="";b4.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;";cf.boxSizing=(b4.offsetWidth===4);cf.doesNotIncludeMarginInBodyOffset=(e.offsetTop!==1);if(a3.getComputedStyle){cf.pixelPosition=(a3.getComputedStyle(b4,null)||{}).top!=="1%";cf.boxSizingReliable=(a3.getComputedStyle(b4,null)||{width:"4px"}).width==="4px";cj=b4.appendChild(l.createElement("div"));cj.style.cssText=b4.style.cssText=ch;cj.style.marginRight=cj.style.width="0";b4.style.width="1px";cf.reliableMarginRight=!parseFloat((a3.getComputedStyle(cj,null)||{}).marginRight)}if(typeof b4.style.zoom!==aD){b4.innerHTML="";b4.style.cssText=ch+"width:1px;padding:1px;display:inline;zoom:1";cf.inlineBlockNeedsLayout=(b4.offsetWidth===3);b4.style.display="block";b4.innerHTML="
    ";b4.firstChild.style.width="5px";cf.shrinkWrapBlocks=(b4.offsetWidth!==3);if(cf.inlineBlockNeedsLayout){e.style.zoom=1}}e.removeChild(cg);cg=b4=ci=cj=null});ce=cd=ca=b6=cc=cb=null;return cf})();var bx=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,aO=/([A-Z])/g;function bb(b6,b4,b8,b7){if(!bK.acceptData(b6)){return}var b9,cb,cc=bK.expando,ca=typeof b4==="string",cd=b6.nodeType,e=cd?bK.cache:b6,b5=cd?b6[cc]:b6[cc]&&cc;if((!b5||!e[b5]||(!b7&&!e[b5].data))&&ca&&b8===aH){return}if(!b5){if(cd){b6[cc]=b5=a7.pop()||bK.guid++}else{b5=cc}}if(!e[b5]){e[b5]={};if(!cd){e[b5].toJSON=bK.noop}}if(typeof b4==="object"||typeof b4==="function"){if(b7){e[b5]=bK.extend(e[b5],b4)}else{e[b5].data=bK.extend(e[b5].data,b4)}}b9=e[b5];if(!b7){if(!b9.data){b9.data={}}b9=b9.data}if(b8!==aH){b9[bK.camelCase(b4)]=b8}if(ca){cb=b9[b4];if(cb==null){cb=b9[bK.camelCase(b4)]}}else{cb=b9}return cb}function aa(b6,b4,b7){if(!bK.acceptData(b6)){return}var b9,b8,ca,cb=b6.nodeType,e=cb?bK.cache:b6,b5=cb?b6[bK.expando]:bK.expando;if(!e[b5]){return}if(b4){ca=b7?e[b5]:e[b5].data;if(ca){if(!bK.isArray(b4)){if(b4 in ca){b4=[b4]}else{b4=bK.camelCase(b4);if(b4 in ca){b4=[b4]}else{b4=b4.split(" ")}}}else{b4=b4.concat(bK.map(b4,bK.camelCase))}for(b9=0,b8=b4.length;b91,null,true)},removeData:function(e){return this.each(function(){bK.removeData(this,e)})}});function bz(b6,b5,b7){if(b7===aH&&b6.nodeType===1){var b4="data-"+b5.replace(aO,"-$1").toLowerCase();b7=b6.getAttribute(b4);if(typeof b7==="string"){try{b7=b7==="true"?true:b7==="false"?false:b7==="null"?null:+b7+""===b7?+b7:bx.test(b7)?bK.parseJSON(b7):b7}catch(b8){}bK.data(b6,b5,b7)}else{b7=aH}}return b7}function O(b4){var e;for(e in b4){if(e==="data"&&bK.isEmptyObject(b4[e])){continue}if(e!=="toJSON"){return false}}return true}bK.extend({queue:function(b5,b4,b6){var e;if(b5){b4=(b4||"fx")+"queue";e=bK._data(b5,b4);if(b6){if(!e||bK.isArray(b6)){e=bK._data(b5,b4,bK.makeArray(b6))}else{e.push(b6)}}return e||[]}},dequeue:function(b8,b7){b7=b7||"fx";var b4=bK.queue(b8,b7),b9=b4.length,b6=b4.shift(),e=bK._queueHooks(b8,b7),b5=function(){bK.dequeue(b8,b7)};if(b6==="inprogress"){b6=b4.shift();b9--}e.cur=b6;if(b6){if(b7==="fx"){b4.unshift("inprogress")}delete e.stop;b6.call(b8,b5,e)}if(!b9&&e){e.empty.fire()}},_queueHooks:function(b5,b4){var e=b4+"queueHooks";return bK._data(b5,e)||bK._data(b5,e,{empty:bK.Callbacks("once memory").add(function(){bK._removeData(b5,b4+"queue");bK._removeData(b5,e)})})}});bK.fn.extend({queue:function(e,b4){var b5=2;if(typeof e!=="string"){b4=e;e="fx";b5--}if(arguments.length1)},removeAttr:function(e){return this.each(function(){bK.removeAttr(this,e)})},prop:function(e,b4){return bK.access(this,bK.prop,e,b4,arguments.length>1)},removeProp:function(e){e=bK.propFix[e]||e;return this.each(function(){try{this[e]=aH;delete this[e]}catch(b4){}})},addClass:function(ca){var b4,e,cb,b7,b5,b6=0,b8=this.length,b9=typeof ca==="string"&&ca;if(bK.isFunction(ca)){return this.each(function(cc){bK(this).addClass(ca.call(this,cc,this.className))})}if(b9){b4=(ca||"").match(ad)||[];for(;b6=0){cb=cb.replace(" "+b7+" "," ")}}e.className=ca?bK.trim(cb):""}}}return this},toggleClass:function(b6,b4){var b5=typeof b6,e=typeof b4==="boolean";if(bK.isFunction(b6)){return this.each(function(b7){bK(this).toggleClass(b6.call(this,b7,this.className,b4),b4)})}return this.each(function(){if(b5==="string"){var b9,b8=0,b7=bK(this),ca=b4,cb=b6.match(ad)||[];while((b9=cb[b8++])){ca=e?ca:!b7.hasClass(b9);b7[ca?"addClass":"removeClass"](b9)}}else{if(b5===aD||b5==="boolean"){if(this.className){bK._data(this,"__className__",this.className)}this.className=this.className||b6===false?"":bK._data(this,"__className__")||""}}})},hasClass:function(e){var b6=" "+e+" ",b5=0,b4=this.length;for(;b5=0){return true}}return false},val:function(b6){var b4,e,b7,b5=this[0];if(!arguments.length){if(b5){e=bK.valHooks[b5.type]||bK.valHooks[b5.nodeName.toLowerCase()];if(e&&"get" in e&&(b4=e.get(b5,"value"))!==aH){return b4}b4=b5.value;return typeof b4==="string"?b4.replace(al,""):b4==null?"":b4}return}b7=bK.isFunction(b6);return this.each(function(b9){var ca,b8=bK(this);if(this.nodeType!==1){return}if(b7){ca=b6.call(this,b9,b8.val())}else{ca=b6}if(ca==null){ca=""}else{if(typeof ca==="number"){ca+=""}else{if(bK.isArray(ca)){ca=bK.map(ca,function(cb){return cb==null?"":cb+""})}}}e=bK.valHooks[this.type]||bK.valHooks[this.nodeName.toLowerCase()];if(!e||!("set" in e)||e.set(this,ca,"value")===aH){this.value=ca}})}});bK.extend({valHooks:{option:{get:function(e){var b4=e.attributes.value;return !b4||b4.specified?e.value:e.text}},select:{get:function(e){var b9,b5,cb=e.options,b7=e.selectedIndex,b6=e.type==="select-one"||b7<0,ca=b6?null:[],b8=b6?b7+1:cb.length,b4=b7<0?b8:b6?b7:0;for(;b4=0});if(!e.length){b4.selectedIndex=-1}return e}}},attr:function(b8,b6,b9){var e,b7,b5,b4=b8.nodeType;if(!b8||b4===3||b4===8||b4===2){return}if(typeof b8.getAttribute===aD){return bK.prop(b8,b6,b9)}b7=b4!==1||!bK.isXMLDoc(b8);if(b7){b6=b6.toLowerCase();e=bK.attrHooks[b6]||(M.test(b6)?b0:a9)}if(b9!==aH){if(b9===null){bK.removeAttr(b8,b6)}else{if(e&&b7&&"set" in e&&(b5=e.set(b8,b9,b6))!==aH){return b5}else{b8.setAttribute(b6,b9+"");return b9}}}else{if(e&&b7&&"get" in e&&(b5=e.get(b8,b6))!==null){return b5}else{if(typeof b8.getAttribute!==aD){b5=b8.getAttribute(b6)}return b5==null?aH:b5}}},removeAttr:function(b5,b7){var e,b6,b4=0,b8=b7&&b7.match(ad);if(b8&&b5.nodeType===1){while((e=b8[b4++])){b6=bK.propFix[e]||e;if(M.test(e)){if(!bQ&&ar.test(e)){b5[bK.camelCase("default-"+e)]=b5[b6]=false}else{b5[b6]=false}}else{bK.attr(b5,e,"")}b5.removeAttribute(bQ?e:b6)}}},attrHooks:{type:{set:function(e,b4){if(!bK.support.radioValue&&b4==="radio"&&bK.nodeName(e,"input")){var b5=e.value;e.setAttribute("type",b4);if(b5){e.value=b5}return b4}}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(b8,b6,b9){var b5,e,b7,b4=b8.nodeType;if(!b8||b4===3||b4===8||b4===2){return}b7=b4!==1||!bK.isXMLDoc(b8);if(b7){b6=bK.propFix[b6]||b6;e=bK.propHooks[b6]}if(b9!==aH){if(e&&"set" in e&&(b5=e.set(b8,b9,b6))!==aH){return b5}else{return(b8[b6]=b9)}}else{if(e&&"get" in e&&(b5=e.get(b8,b6))!==null){return b5}else{return b8[b6]}}},propHooks:{tabIndex:{get:function(b4){var e=b4.getAttributeNode("tabindex");return e&&e.specified?parseInt(e.value,10):aG.test(b4.nodeName)||E.test(b4.nodeName)&&b4.href?0:aH}}}});b0={get:function(b6,b4){var b7=bK.prop(b6,b4),e=typeof b7==="boolean"&&b6.getAttribute(b4),b5=typeof b7==="boolean"?bG&&bQ?e!=null:ar.test(b4)?b6[bK.camelCase("default-"+b4)]:!!e:b6.getAttributeNode(b4);return b5&&b5.value!==false?b4.toLowerCase():aH},set:function(b4,b5,e){if(b5===false){bK.removeAttr(b4,e)}else{if(bG&&bQ||!ar.test(e)){b4.setAttribute(!bQ&&bK.propFix[e]||e,e)}else{b4[bK.camelCase("default-"+e)]=b4[e]=true}}return e}};if(!bG||!bQ){bK.attrHooks.value={get:function(b5,b4){var e=b5.getAttributeNode(b4);return bK.nodeName(b5,"input")?b5.defaultValue:e&&e.specified?e.value:aH},set:function(b4,b5,e){if(bK.nodeName(b4,"input")){b4.defaultValue=b5}else{return a9&&a9.set(b4,b5,e)}}}}if(!bQ){a9=bK.valHooks.button={get:function(b5,b4){var e=b5.getAttributeNode(b4);return e&&(b4==="id"||b4==="name"||b4==="coords"?e.value!=="":e.specified)?e.value:aH},set:function(b5,b6,b4){var e=b5.getAttributeNode(b4);if(!e){b5.setAttributeNode((e=b5.ownerDocument.createAttribute(b4)))}e.value=b6+="";return b4==="value"||b6===b5.getAttribute(b4)?b6:aH}};bK.attrHooks.contenteditable={get:a9.get,set:function(b4,b5,e){a9.set(b4,b5===""?false:b5,e)}};bK.each(["width","height"],function(b4,e){bK.attrHooks[e]=bK.extend(bK.attrHooks[e],{set:function(b5,b6){if(b6===""){b5.setAttribute(e,"auto");return b6}}})})}if(!bK.support.hrefNormalized){bK.each(["href","src","width","height"],function(b4,e){bK.attrHooks[e]=bK.extend(bK.attrHooks[e],{get:function(b6){var b5=b6.getAttribute(e,2);return b5==null?aH:b5}})});bK.each(["href","src"],function(b4,e){bK.propHooks[e]={get:function(b5){return b5.getAttribute(e,4)}}})}if(!bK.support.style){bK.attrHooks.style={get:function(e){return e.style.cssText||aH},set:function(e,b4){return(e.style.cssText=b4+"")}}}if(!bK.support.optSelected){bK.propHooks.selected=bK.extend(bK.propHooks.selected,{get:function(b4){var e=b4.parentNode;if(e){e.selectedIndex;if(e.parentNode){e.parentNode.selectedIndex}}return null}})}if(!bK.support.enctype){bK.propFix.enctype="encoding"}if(!bK.support.checkOn){bK.each(["radio","checkbox"],function(){bK.valHooks[this]={get:function(e){return e.getAttribute("value")===null?"on":e.value}}})}bK.each(["radio","checkbox"],function(){bK.valHooks[this]=bK.extend(bK.valHooks[this],{set:function(e,b4){if(bK.isArray(b4)){return(e.checked=bK.inArray(bK(e).val(),b4)>=0)}}})});var bI=/^(?:input|select|textarea)$/i,a4=/^key/,bO=/^(?:mouse|contextmenu)|click/,bC=/^(?:focusinfocus|focusoutblur)$/,bv=/^([^.]*)(?:\.(.+)|)$/;function S(){return true}function Y(){return false}bK.event={global:{},add:function(b7,cc,ch,b9,b8){var ca,ci,cj,b5,ce,cb,cg,b6,cf,e,b4,cd=bK._data(b7);if(!cd){return}if(ch.handler){b5=ch;ch=b5.handler;b8=b5.selector}if(!ch.guid){ch.guid=bK.guid++}if(!(ci=cd.events)){ci=cd.events={}}if(!(cb=cd.handle)){cb=cd.handle=function(ck){return typeof bK!==aD&&(!ck||bK.event.triggered!==ck.type)?bK.event.dispatch.apply(cb.elem,arguments):aH};cb.elem=b7}cc=(cc||"").match(ad)||[""];cj=cc.length;while(cj--){ca=bv.exec(cc[cj])||[];cf=b4=ca[1];e=(ca[2]||"").split(".").sort();ce=bK.event.special[cf]||{};cf=(b8?ce.delegateType:ce.bindType)||cf;ce=bK.event.special[cf]||{};cg=bK.extend({type:cf,origType:b4,data:b9,handler:ch,guid:ch.guid,selector:b8,needsContext:b8&&bK.expr.match.needsContext.test(b8),namespace:e.join(".")},b5);if(!(b6=ci[cf])){b6=ci[cf]=[];b6.delegateCount=0;if(!ce.setup||ce.setup.call(b7,b9,e,cb)===false){if(b7.addEventListener){b7.addEventListener(cf,cb,false)}else{if(b7.attachEvent){b7.attachEvent("on"+cf,cb)}}}}if(ce.add){ce.add.call(b7,cg);if(!cg.handler.guid){cg.handler.guid=ch.guid}}if(b8){b6.splice(b6.delegateCount++,0,cg)}else{b6.push(cg)}bK.event.global[cf]=true}b7=null},remove:function(b6,cc,cj,b7,cb){var b9,cg,ca,b8,ci,ch,ce,b5,cf,e,b4,cd=bK.hasData(b6)&&bK._data(b6);if(!cd||!(ch=cd.events)){return}cc=(cc||"").match(ad)||[""];ci=cc.length;while(ci--){ca=bv.exec(cc[ci])||[];cf=b4=ca[1];e=(ca[2]||"").split(".").sort();if(!cf){for(cf in ch){bK.event.remove(b6,cf+cc[ci],cj,b7,true)}continue}ce=bK.event.special[cf]||{};cf=(b7?ce.delegateType:ce.bindType)||cf;b5=ch[cf]||[];ca=ca[2]&&new RegExp("(^|\\.)"+e.join("\\.(?:.*\\.|)")+"(\\.|$)");b8=b9=b5.length;while(b9--){cg=b5[b9];if((cb||b4===cg.origType)&&(!cj||cj.guid===cg.guid)&&(!ca||ca.test(cg.namespace))&&(!b7||b7===cg.selector||b7==="**"&&cg.selector)){b5.splice(b9,1);if(cg.selector){b5.delegateCount--}if(ce.remove){ce.remove.call(b6,cg)}}}if(b8&&!b5.length){if(!ce.teardown||ce.teardown.call(b6,e,cd.handle)===false){bK.removeEvent(b6,cf,cd.handle)}delete ch[cf]}}if(bK.isEmptyObject(ch)){delete cd.handle;bK._removeData(b6,"events")}},trigger:function(b4,cb,b7,ci){var cc,b6,cg,ch,ce,ca,b9,b8=[b7||l],cf=W.call(b4,"type")?b4.type:b4,b5=W.call(b4,"namespace")?b4.namespace.split("."):[];cg=ca=b7=b7||l;if(b7.nodeType===3||b7.nodeType===8){return}if(bC.test(cf+bK.event.triggered)){return}if(cf.indexOf(".")>=0){b5=cf.split(".");cf=b5.shift();b5.sort()}b6=cf.indexOf(":")<0&&"on"+cf;b4=b4[bK.expando]?b4:new bK.Event(cf,typeof b4==="object"&&b4);b4.isTrigger=true;b4.namespace=b5.join(".");b4.namespace_re=b4.namespace?new RegExp("(^|\\.)"+b5.join("\\.(?:.*\\.|)")+"(\\.|$)"):null;b4.result=aH;if(!b4.target){b4.target=b7}cb=cb==null?[b4]:bK.makeArray(cb,[b4]);ce=bK.event.special[cf]||{};if(!ci&&ce.trigger&&ce.trigger.apply(b7,cb)===false){return}if(!ci&&!ce.noBubble&&!bK.isWindow(b7)){ch=ce.delegateType||cf;if(!bC.test(ch+cf)){cg=cg.parentNode}for(;cg;cg=cg.parentNode){b8.push(cg);ca=cg}if(ca===(b7.ownerDocument||l)){b8.push(ca.defaultView||ca.parentWindow||a3)}}b9=0;while((cg=b8[b9++])&&!b4.isPropagationStopped()){b4.type=b9>1?ch:ce.bindType||cf;cc=(bK._data(cg,"events")||{})[b4.type]&&bK._data(cg,"handle");if(cc){cc.apply(cg,cb)}cc=b6&&cg[b6];if(cc&&bK.acceptData(cg)&&cc.apply&&cc.apply(cg,cb)===false){b4.preventDefault()}}b4.type=cf;if(!ci&&!b4.isDefaultPrevented()){if((!ce._default||ce._default.apply(b7.ownerDocument,cb)===false)&&!(cf==="click"&&bK.nodeName(b7,"a"))&&bK.acceptData(b7)){if(b6&&b7[cf]&&!bK.isWindow(b7)){ca=b7[b6];if(ca){b7[b6]=null}bK.event.triggered=cf;try{b7[cf]()}catch(cd){}bK.event.triggered=aH;if(ca){b7[b6]=ca}}}}return b4.result},dispatch:function(e){e=bK.event.fix(e);var b7,b8,cc,b4,b6,cb=[],ca=a5.call(arguments),b5=(bK._data(this,"events")||{})[e.type]||[],b9=bK.event.special[e.type]||{};ca[0]=e;e.delegateTarget=this;if(b9.preDispatch&&b9.preDispatch.call(this,e)===false){return}cb=bK.event.handlers.call(this,e,b5);b7=0;while((b4=cb[b7++])&&!e.isPropagationStopped()){e.currentTarget=b4.elem;b6=0;while((cc=b4.handlers[b6++])&&!e.isImmediatePropagationStopped()){if(!e.namespace_re||e.namespace_re.test(cc.namespace)){e.handleObj=cc;e.data=cc.data;b8=((bK.event.special[cc.origType]||{}).handle||cc.handler).apply(b4.elem,ca);if(b8!==aH){if((e.result=b8)===false){e.preventDefault();e.stopPropagation()}}}}}if(b9.postDispatch){b9.postDispatch.call(this,e)}return e.result},handlers:function(e,b5){var b4,ca,b8,b7,b9=[],b6=b5.delegateCount,cb=e.target;if(b6&&cb.nodeType&&(!e.button||e.type!=="click")){for(;cb!=this;cb=cb.parentNode||this){if(cb.nodeType===1&&(cb.disabled!==true||e.type!=="click")){b8=[];for(b7=0;b7=0:bK.find(b4,this,null,[cb]).length}if(b8[b4]){b8.push(ca)}}if(b8.length){b9.push({elem:cb,handlers:b8})}}}}if(b6+~])"+cq+"*"),cQ=new RegExp(cl),cR=new RegExp("^"+cL+"$"),cZ={ID:new RegExp("^#("+b4+")"),CLASS:new RegExp("^\\.("+b4+")"),NAME:new RegExp("^\\[name=['\"]?("+b4+")['\"]?\\]"),TAG:new RegExp("^("+b4.replace("w","w*")+")"),ATTR:new RegExp("^"+c3),PSEUDO:new RegExp("^"+cl),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+cq+"*(even|odd|(([+-]|)(\\d*)n|)"+cq+"*(?:([+-]|)"+cq+"*(\\d+)|))"+cq+"*\\)|)","i"),needsContext:new RegExp("^"+cq+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+cq+"*((?:-\\d)?\\d*)"+cq+"*\\)|)(?=[^-]|$)","i")},cX=/[\x20\t\r\n\f]*[+~]/,cN=/^[^{]+\{\s*\[native code/,cP=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,b9=/^(?:input|select|textarea|button)$/i,cm=/^h\d$/i,cM=/'|\\/g,cu=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,ct=/\\([\da-fA-F]{1,6}[\x20\t\r\n\f]?|.)/g,c2=function(e,dj){var di="0x"+dj-65536;return di!==di?dj:di<0?String.fromCharCode(di+65536):String.fromCharCode(di>>10|55296,di&1023|56320)};try{cn.call(cJ.documentElement.childNodes,0)[0].nodeType}catch(cD){cn=function(di){var dj,e=[];while((dj=this[di++])){e.push(dj)}return e}}function cF(e){return cN.test(e+"")}function cA(){var e,di=[];return(e=function(dj,dk){if(di.push(dj+=" ")>co.cacheLength){delete e[di.shift()]}return(e[dj]=dk)})}function ck(e){e[c6]=true;return e}function cd(di){var dk=cC.createElement("div");try{return di(dk)}catch(dj){return false}finally{dk=null}}function cw(dq,di,du,dw){var dv,dm,dn,ds,dt,dl,dk,e,dj,dr;if((di?di.ownerDocument||di:cJ)!==cC){cW(di)}di=di||cC;du=du||[];if(!dq||typeof dq!=="string"){return du}if((ds=di.nodeType)!==1&&ds!==9){return[]}if(!ce&&!dw){if((dv=cP.exec(dq))){if((dn=dv[1])){if(ds===9){dm=di.getElementById(dn);if(dm&&dm.parentNode){if(dm.id===dn){du.push(dm);return du}}else{return du}}else{if(di.ownerDocument&&(dm=di.ownerDocument.getElementById(dn))&&cG(di,dm)&&dm.id===dn){du.push(dm);return du}}}else{if(dv[2]){b5.apply(du,cn.call(di.getElementsByTagName(dq),0));return du}else{if((dn=dv[3])&&de.getByClassName&&di.getElementsByClassName){b5.apply(du,cn.call(di.getElementsByClassName(dn),0));return du}}}}if(de.qsa&&!c0.test(dq)){dk=true;e=c6;dj=di;dr=ds===9&&dq;if(ds===1&&di.nodeName.toLowerCase()!=="object"){dl=cg(dq);if((dk=di.getAttribute("id"))){e=dk.replace(cM,"\\$&")}else{di.setAttribute("id",e)}e="[id='"+e+"'] ";dt=dl.length;while(dt--){dl[dt]=e+ch(dl[dt])}dj=cX.test(dq)&&di.parentNode||di;dr=dl.join(",")}if(dr){try{b5.apply(du,cn.call(dj.querySelectorAll(dr),0));return du}catch(dp){}finally{if(!dk){di.removeAttribute("id")}}}}}return dd(dq.replace(cs,"$1"),di,du,dw)}cK=cw.isXML=function(e){var di=e&&(e.ownerDocument||e).documentElement;return di?di.nodeName!=="HTML":false};cW=cw.setDocument=function(e){var di=e?e.ownerDocument||e:cJ;if(di===cC||di.nodeType!==9||!di.documentElement){return cC}cC=di;cp=di.documentElement;ce=cK(di);de.tagNameNoComments=cd(function(dj){dj.appendChild(di.createComment(""));return !dj.getElementsByTagName("*").length});de.attributes=cd(function(dk){dk.innerHTML="";var dj=typeof dk.lastChild.getAttribute("multiple");return dj!=="boolean"&&dj!=="string"});de.getByClassName=cd(function(dj){dj.innerHTML="";if(!dj.getElementsByClassName||!dj.getElementsByClassName("e").length){return false}dj.lastChild.className="e";return dj.getElementsByClassName("e").length===2});de.getByName=cd(function(dk){dk.id=c6+0;dk.innerHTML="
    ";cp.insertBefore(dk,cp.firstChild);var dj=di.getElementsByName&&di.getElementsByName(c6).length===2+di.getElementsByName(c6+0).length;de.getIdNotName=!di.getElementById(c6);cp.removeChild(dk);return dj});co.attrHandle=cd(function(dj){dj.innerHTML="";return dj.firstChild&&typeof dj.firstChild.getAttribute!==da&&dj.firstChild.getAttribute("href")==="#"})?{}:{href:function(dj){return dj.getAttribute("href",2)},type:function(dj){return dj.getAttribute("type")}};if(de.getIdNotName){co.find.ID=function(dl,dk){if(typeof dk.getElementById!==da&&!ce){var dj=dk.getElementById(dl);return dj&&dj.parentNode?[dj]:[]}};co.filter.ID=function(dk){var dj=dk.replace(ct,c2);return function(dl){return dl.getAttribute("id")===dj}}}else{co.find.ID=function(dl,dk){if(typeof dk.getElementById!==da&&!ce){var dj=dk.getElementById(dl);return dj?dj.id===dl||typeof dj.getAttributeNode!==da&&dj.getAttributeNode("id").value===dl?[dj]:ci:[]}};co.filter.ID=function(dk){var dj=dk.replace(ct,c2);return function(dm){var dl=typeof dm.getAttributeNode!==da&&dm.getAttributeNode("id");return dl&&dl.value===dj}}}co.find.TAG=de.tagNameNoComments?function(dj,dk){if(typeof dk.getElementsByTagName!==da){return dk.getElementsByTagName(dj)}}:function(dj,dn){var dp,dm=[],dl=0,dk=dn.getElementsByTagName(dj);if(dj==="*"){while((dp=dk[dl++])){if(dp.nodeType===1){dm.push(dp)}}return dm}return dk};co.find.NAME=de.getByName&&function(dj,dk){if(typeof dk.getElementsByName!==da){return dk.getElementsByName(name)}};co.find.CLASS=de.getByClassName&&function(dk,dj){if(typeof dj.getElementsByClassName!==da&&!ce){return dj.getElementsByClassName(dk)}};dc=[];c0=[":focus"];if((de.qsa=cF(di.querySelectorAll))){cd(function(dj){dj.innerHTML="";if(!dj.querySelectorAll("[selected]").length){c0.push("\\["+cq+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)")}if(!dj.querySelectorAll(":checked").length){c0.push(":checked")}});cd(function(dj){dj.innerHTML="";if(dj.querySelectorAll("[i^='']").length){c0.push("[*^$]="+cq+"*(?:\"\"|'')")}if(!dj.querySelectorAll(":enabled").length){c0.push(":enabled",":disabled")}dj.querySelectorAll("*,:x");c0.push(",.*:")})}if((de.matchesSelector=cF((cb=cp.matchesSelector||cp.mozMatchesSelector||cp.webkitMatchesSelector||cp.oMatchesSelector||cp.msMatchesSelector)))){cd(function(dj){de.disconnectedMatch=cb.call(dj,"div");cb.call(dj,"[s!='']:x");dc.push("!=",cl)})}c0=new RegExp(c0.join("|"));dc=new RegExp(dc.join("|"));cG=cF(cp.contains)||cp.compareDocumentPosition?function(dk,dj){var dm=dk.nodeType===9?dk.documentElement:dk,dl=dj&&dj.parentNode;return dk===dl||!!(dl&&dl.nodeType===1&&(dm.contains?dm.contains(dl):dk.compareDocumentPosition&&dk.compareDocumentPosition(dl)&16))}:function(dk,dj){if(dj){while((dj=dj.parentNode)){if(dj===dk){return true}}}return false};cE=cp.compareDocumentPosition?function(dk,dj){var dl;if(dk===dj){cU=true;return 0}if((dl=dj.compareDocumentPosition&&dk.compareDocumentPosition&&dk.compareDocumentPosition(dj))){if(dl&1||dk.parentNode&&dk.parentNode.nodeType===11){if(dk===di||cG(cJ,dk)){return -1}if(dj===di||cG(cJ,dj)){return 1}return 0}return dl&4?-1:1}return dk.compareDocumentPosition?-1:1}:function(dk,dj){var dr,dn=0,dq=dk.parentNode,dm=dj.parentNode,dl=[dk],dp=[dj];if(dk===dj){cU=true;return 0}else{if(!dq||!dm){return dk===di?-1:dj===di?1:dq?-1:dm?1:0}else{if(dq===dm){return b7(dk,dj)}}}dr=dk;while((dr=dr.parentNode)){dl.unshift(dr)}dr=dj;while((dr=dr.parentNode)){dp.unshift(dr)}while(dl[dn]===dp[dn]){dn++}return dn?b7(dl[dn],dp[dn]):dl[dn]===cJ?-1:dp[dn]===cJ?1:0};cU=false;[0,0].sort(cE);de.detectDuplicates=cU;return cC};cw.matches=function(di,e){return cw(di,null,null,e)};cw.matchesSelector=function(dj,dl){if((dj.ownerDocument||dj)!==cC){cW(dj)}dl=dl.replace(cu,"='$1']");if(de.matchesSelector&&!ce&&(!dc||!dc.test(dl))&&!c0.test(dl)){try{var di=cb.call(dj,dl);if(di||de.disconnectedMatch||dj.document&&dj.document.nodeType!==11){return di}}catch(dk){}}return cw(dl,cC,null,[dj]).length>0};cw.contains=function(e,di){if((e.ownerDocument||e)!==cC){cW(e)}return cG(e,di)};cw.attr=function(di,e){var dj;if((di.ownerDocument||di)!==cC){cW(di)}if(!ce){e=e.toLowerCase()}if((dj=co.attrHandle[e])){return dj(di)}if(ce||de.attributes){return di.getAttribute(e)}return((dj=di.getAttributeNode(e))||di.getAttribute(e))&&di[e]===true?e:dj&&dj.specified?dj.value:null};cw.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)};cw.uniqueSort=function(dj){var dk,dl=[],di=1,e=0;cU=!de.detectDuplicates;dj.sort(cE);if(cU){for(;(dk=dj[di]);di++){if(dk===dj[di-1]){e=dl.push(di)}}while(e--){dj.splice(dl[e],1)}}return dj};function b7(di,e){var dk=e&&di,dj=dk&&(~e.sourceIndex||cO)-(~di.sourceIndex||cO);if(dj){return dj}if(dk){while((dk=dk.nextSibling)){if(dk===e){return -1}}}return di?1:-1}function cx(e){return function(dj){var di=dj.nodeName.toLowerCase();return di==="input"&&dj.type===e}}function b8(e){return function(dj){var di=dj.nodeName.toLowerCase();return(di==="input"||di==="button")&&dj.type===e}}function c4(e){return ck(function(di){di=+di;return ck(function(dj,dn){var dl,dk=e([],dj.length,di),dm=dk.length;while(dm--){if(dj[(dl=dk[dm])]){dj[dl]=!(dn[dl]=dj[dl])}}})})}cI=cw.getText=function(dl){var dk,di="",dj=0,e=dl.nodeType;if(!e){for(;(dk=dl[dj]);dj++){di+=cI(dk)}}else{if(e===1||e===9||e===11){if(typeof dl.textContent==="string"){return dl.textContent}else{for(dl=dl.firstChild;dl;dl=dl.nextSibling){di+=cI(dl)}}}else{if(e===3||e===4){return dl.nodeValue}}}return di};co=cw.selectors={cacheLength:50,createPseudo:ck,match:cZ,find:{},relative:{">":{dir:"parentNode",first:true}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:true},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){e[1]=e[1].replace(ct,c2);e[3]=(e[4]||e[5]||"").replace(ct,c2);if(e[2]==="~="){e[3]=" "+e[3]+" "}return e.slice(0,4)},CHILD:function(e){e[1]=e[1].toLowerCase();if(e[1].slice(0,3)==="nth"){if(!e[3]){cw.error(e[0])}e[4]=+(e[4]?e[5]+(e[6]||1):2*(e[3]==="even"||e[3]==="odd"));e[5]=+((e[7]+e[8])||e[3]==="odd")}else{if(e[3]){cw.error(e[0])}}return e},PSEUDO:function(di){var e,dj=!di[5]&&di[2];if(cZ.CHILD.test(di[0])){return null}if(di[4]){di[2]=di[4]}else{if(dj&&cQ.test(dj)&&(e=cg(dj,true))&&(e=dj.indexOf(")",dj.length-e)-dj.length)){di[0]=di[0].slice(0,e);di[2]=dj.slice(0,e)}}return di.slice(0,3)}},filter:{TAG:function(e){if(e==="*"){return function(){return true}}e=e.replace(ct,c2).toLowerCase();return function(di){return di.nodeName&&di.nodeName.toLowerCase()===e}},CLASS:function(e){var di=b6[e+" "];return di||(di=new RegExp("(^|"+cq+")"+e+"("+cq+"|$)"))&&b6(e,function(dj){return di.test(dj.className||(typeof dj.getAttribute!==da&&dj.getAttribute("class"))||"")})},ATTR:function(dj,di,e){return function(dl){var dk=cw.attr(dl,dj);if(dk==null){return di==="!="}if(!di){return true}dk+="";return di==="="?dk===e:di==="!="?dk!==e:di==="^="?e&&dk.indexOf(e)===0:di==="*="?e&&dk.indexOf(e)>-1:di==="$="?e&&dk.slice(-e.length)===e:di==="~="?(" "+dk+" ").indexOf(e)>-1:di==="|="?dk===e||dk.slice(0,e.length+1)===e+"-":false}},CHILD:function(di,dl,dk,dm,dj){var dp=di.slice(0,3)!=="nth",e=di.slice(-4)!=="last",dn=dl==="of-type";return dm===1&&dj===0?function(dq){return !!dq.parentNode}:function(dw,du,dz){var dq,dC,dx,dB,dy,dt,dv=dp!==e?"nextSibling":"previousSibling",dA=dw.parentNode,ds=dn&&dw.nodeName.toLowerCase(),dr=!dz&&!dn;if(dA){if(dp){while(dv){dx=dw;while((dx=dx[dv])){if(dn?dx.nodeName.toLowerCase()===ds:dx.nodeType===1){return false}}dt=dv=di==="only"&&!dt&&"nextSibling"}return true}dt=[e?dA.firstChild:dA.lastChild];if(e&&dr){dC=dA[c6]||(dA[c6]={});dq=dC[di]||[];dy=dq[0]===df&&dq[1];dB=dq[0]===df&&dq[2];dx=dy&&dA.childNodes[dy];while((dx=++dy&&dx&&dx[dv]||(dB=dy=0)||dt.pop())){if(dx.nodeType===1&&++dB&&dx===dw){dC[di]=[df,dy,dB];break}}}else{if(dr&&(dq=(dw[c6]||(dw[c6]={}))[di])&&dq[0]===df){dB=dq[1]}else{while((dx=++dy&&dx&&dx[dv]||(dB=dy=0)||dt.pop())){if((dn?dx.nodeName.toLowerCase()===ds:dx.nodeType===1)&&++dB){if(dr){(dx[c6]||(dx[c6]={}))[di]=[df,dB]}if(dx===dw){break}}}}}dB-=dj;return dB===dm||(dB%dm===0&&dB/dm>=0)}}},PSEUDO:function(dk,dj){var e,di=co.pseudos[dk]||co.setFilters[dk.toLowerCase()]||cw.error("unsupported pseudo: "+dk);if(di[c6]){return di(dj)}if(di.length>1){e=[dk,dk,"",dj];return co.setFilters.hasOwnProperty(dk.toLowerCase())?ck(function(dn,dq){var dm,dl=di(dn,dj),dp=dl.length;while(dp--){dm=ca.call(dn,dl[dp]);dn[dm]=!(dq[dm]=dl[dp])}}):function(dl){return di(dl,0,e)}}return di}},pseudos:{not:ck(function(e){var di=[],dj=[],dk=cT(e.replace(cs,"$1"));return dk[c6]?ck(function(dm,ds,dq,dn){var dr,dl=dk(dm,null,dn,[]),dp=dm.length;while(dp--){if((dr=dl[dp])){dm[dp]=!(ds[dp]=dr)}}}):function(dn,dm,dl){di[0]=dn;dk(di,null,dl,dj);return !dj.pop()}}),has:ck(function(e){return function(di){return cw(e,di).length>0}}),contains:ck(function(e){return function(di){return(di.textContent||di.innerText||cI(di)).indexOf(e)>-1}}),lang:ck(function(e){if(!cR.test(e||"")){cw.error("unsupported lang: "+e)}e=e.replace(ct,c2).toLowerCase();return function(dj){var di;do{if((di=ce?dj.getAttribute("xml:lang")||dj.getAttribute("lang"):dj.lang)){di=di.toLowerCase();return di===e||di.indexOf(e+"-")===0}}while((dj=dj.parentNode)&&dj.nodeType===1);return false}}),target:function(e){var di=db.location&&db.location.hash;return di&&di.slice(1)===e.id},root:function(e){return e===cp},focus:function(e){return e===cC.activeElement&&(!cC.hasFocus||cC.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===false},disabled:function(e){return e.disabled===true},checked:function(e){var di=e.nodeName.toLowerCase();return(di==="input"&&!!e.checked)||(di==="option"&&!!e.selected)},selected:function(e){if(e.parentNode){e.parentNode.selectedIndex}return e.selected===true},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling){if(e.nodeName>"@"||e.nodeType===3||e.nodeType===4){return false}}return true},parent:function(e){return !co.pseudos.empty(e)},header:function(e){return cm.test(e.nodeName)},input:function(e){return b9.test(e.nodeName)},button:function(di){var e=di.nodeName.toLowerCase();return e==="input"&&di.type==="button"||e==="button"},text:function(di){var e;return di.nodeName.toLowerCase()==="input"&&di.type==="text"&&((e=di.getAttribute("type"))==null||e.toLowerCase()===di.type)},first:c4(function(){return[0]}),last:c4(function(e,di){return[di-1]}),eq:c4(function(e,dj,di){return[di<0?di+dj:di]}),even:c4(function(e,dj){var di=0;for(;di=0;){e.push(di)}return e}),gt:c4(function(e,dk,dj){var di=dj<0?dj+dk:dj;for(;++di1?function(dl,dk,di){var dj=e.length;while(dj--){if(!e[dj](dl,dk,di)){return false}}return true}:e[0]}function cY(e,di,dj,dk,dn){var dl,dr=[],dm=0,dp=e.length,dq=di!=null;for(;dm-1){dy[dA]=!(dv[dA]=ds)}}}}else{du=cY(du===dv?du.splice(dp,du.length):du);if(dm){dm(null,dv,du,dx)}else{b5.apply(dv,du)}}})}function c7(dn){var di,dl,dj,dm=dn.length,dr=co.relative[dn[0].type],ds=dr||co.relative[" "],dk=dr?1:0,dp=cr(function(dt){return dt===di},ds,true),dq=cr(function(dt){return ca.call(di,dt)>-1},ds,true),e=[function(dv,du,dt){return(!dr&&(dt||du!==dh))||((di=du).nodeType?dp(dv,du,dt):dq(dv,du,dt))}];for(;dk1&&dg(e),dk>1&&ch(dn.slice(0,dk-1)).replace(cs,"$1"),dl,dk0,dl=dk.length>0,di=function(dx,dr,dw,dv,dD){var ds,dt,dy,dC=[],dB=0,du="0",dn=dx&&[],dz=dD!=null,dA=dh,dq=dx||dl&&co.find.TAG("*",dD&&dr.parentNode||dr),dp=(df+=dA==null?1:Math.random()||0.1);if(dz){dh=dr!==cC&&dr;cc=dm}for(;(ds=dq[du])!=null;du++){if(dl&&ds){dt=0;while((dy=dk[dt++])){if(dy(ds,dr,dw)){dv.push(ds);break}}if(dz){df=dp;cc=++dm}}if(e){if((ds=!dy&&ds)){dB--}if(dx){dn.push(ds)}}}dB+=du;if(e&&du!==dB){dt=0;while((dy=dj[dt++])){dy(dn,dC,dr,dw)}if(dx){if(dB>0){while(du--){if(!(dn[du]||dC[du])){dC[du]=c9.call(dv)}}}dC=cY(dC)}b5.apply(dv,dC);if(dz&&!dx&&dC.length>0&&(dB+dj.length)>1){cw.uniqueSort(dv)}}if(dz){df=dp;dh=dA}return dn};return e?ck(di):di}cT=cw.compile=function(e,dm){var dj,di=[],dl=[],dk=cH[e+" "];if(!dk){if(!dm){dm=cg(e)}dj=dm.length;while(dj--){dk=c7(dm[dj]);if(dk[c6]){di.push(dk)}else{dl.push(dk)}}dk=cH(e,cV(dl,di))}return dk};function cz(di,dl,dk){var dj=0,e=dl.length;for(;dj2&&(di=dq[0]).type==="ID"&&e.nodeType===9&&!ce&&co.relative[dq[1].type]){e=co.find.ID(di.matches[0].replace(ct,c2),e)[0];if(!e){return dk}dj=dj.slice(dq.shift().value.length)}dl=cZ.needsContext.test(dj)?0:dq.length;while(dl--){di=dq[dl];if(co.relative[(dr=di.type)]){break}if((dp=co.find[dr])){if((dn=dp(di.matches[0].replace(ct,c2),cX.test(dq[0].type)&&e.parentNode||e))){dq.splice(dl,1);dj=dn.length&&ch(dq);if(!dj){b5.apply(dk,cn.call(dn,0));return dk}break}}}}}cT(dj,dm)(dn,e,ce,dk,cX.test(dj));return dk}co.pseudos.nth=co.pseudos.eq;function cS(){}co.filters=cS.prototype=co.pseudos;co.setFilters=new cS();cW();cw.attr=bK.attr;bK.find=cw;bK.expr=cw.selectors;bK.expr[":"]=bK.expr.pseudos;bK.unique=cw.uniqueSort;bK.text=cw.getText;bK.isXMLDoc=cw.isXML;bK.contains=cw.contains})(a3);var ak=/Until$/,bu=/^(?:parents|prev(?:Until|All))/,ao=/^.[^:#\[\.,]*$/,z=bK.expr.match.needsContext,by={children:true,contents:true,next:true,prev:true};bK.fn.extend({find:function(b4){var b7,b6,b5,e=this.length;if(typeof b4!=="string"){b5=this;return this.pushStack(bK(b4).filter(function(){for(b7=0;b71?bK.unique(b6):b6);b6.selector=(this.selector?this.selector+" ":"")+b4;return b6},has:function(b6){var b5,b4=bK(b6,this),e=b4.length;return this.filter(function(){for(b5=0;b5=0:bK.filter(e,this).length>0:this.filter(e).length>0)},closest:function(b7,b6){var b8,b5=0,e=this.length,b4=[],b9=z.test(b7)||typeof b7!=="string"?bK(b7,b6||this.context):0;for(;b5-1:bK.find.matchesSelector(b8,b7)){b4.push(b8);break}b8=b8.parentNode}}return this.pushStack(b4.length>1?bK.unique(b4):b4)},index:function(e){if(!e){return(this[0]&&this[0].parentNode)?this.first().prevAll().length:-1}if(typeof e==="string"){return bK.inArray(this[0],bK(e))}return bK.inArray(e.jquery?e[0]:e,this)},add:function(e,b4){var b6=typeof e==="string"?bK(e,b4):bK.makeArray(e&&e.nodeType?[e]:e),b5=bK.merge(this.get(),b6);return this.pushStack(bK.unique(b5))},addBack:function(e){return this.add(e==null?this.prevObject:this.prevObject.filter(e))}});bK.fn.andSelf=bK.fn.addBack;function aY(b4,e){do{b4=b4[e]}while(b4&&b4.nodeType!==1);return b4}bK.each({parent:function(b4){var e=b4.parentNode;return e&&e.nodeType!==11?e:null},parents:function(e){return bK.dir(e,"parentNode")},parentsUntil:function(b4,e,b5){return bK.dir(b4,"parentNode",b5)},next:function(e){return aY(e,"nextSibling")},prev:function(e){return aY(e,"previousSibling")},nextAll:function(e){return bK.dir(e,"nextSibling")},prevAll:function(e){return bK.dir(e,"previousSibling")},nextUntil:function(b4,e,b5){return bK.dir(b4,"nextSibling",b5)},prevUntil:function(b4,e,b5){return bK.dir(b4,"previousSibling",b5)},siblings:function(e){return bK.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return bK.sibling(e.firstChild)},contents:function(e){return bK.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:bK.merge([],e.childNodes)}},function(e,b4){bK.fn[e]=function(b7,b5){var b6=bK.map(this,b4,b7);if(!ak.test(e)){b5=b7}if(b5&&typeof b5==="string"){b6=bK.filter(b5,b6)}b6=this.length>1&&!by[e]?bK.unique(b6):b6;if(this.length>1&&bu.test(e)){b6=b6.reverse()}return this.pushStack(b6)}});bK.extend({filter:function(b5,e,b4){if(b4){b5=":not("+b5+")"}return e.length===1?bK.find.matchesSelector(e[0],b5)?[e[0]]:[]:bK.find.matches(b5,e)},dir:function(b5,b4,b7){var e=[],b6=b5[b4];while(b6&&b6.nodeType!==9&&(b7===aH||b6.nodeType!==1||!bK(b6).is(b7))){if(b6.nodeType===1){e.push(b6)}b6=b6[b4]}return e},sibling:function(b5,b4){var e=[];for(;b5;b5=b5.nextSibling){if(b5.nodeType===1&&b5!==b4){e.push(b5)}}return e}});function aP(b6,b5,e){b5=b5||0;if(bK.isFunction(b5)){return bK.grep(b6,function(b8,b7){var b9=!!b5.call(b8,b7,b8);return b9===e})}else{if(b5.nodeType){return bK.grep(b6,function(b7){return(b7===b5)===e})}else{if(typeof b5==="string"){var b4=bK.grep(b6,function(b7){return b7.nodeType===1});if(ao.test(b5)){return bK.filter(b5,b4,!e)}else{b5=bK.filter(b5,b4)}}}}return bK.grep(b6,function(b7){return(bK.inArray(b7,b5)>=0)===e})}function B(e){var b5=d.split("|"),b4=e.createDocumentFragment();if(b4.createElement){while(b5.length){b4.createElement(b5.pop())}}return b4}var d="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",aB=/ jQuery\d+="(?:null|\d+)"/g,K=new RegExp("<(?:"+d+")[\\s/>]","i"),b3=/^\s+/,aE=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,m=/<([\w:]+)/,bY=/\s*$/g,U={option:[1,""],legend:[1,"
    ","
    "],area:[1,"",""],param:[1,"",""],thead:[1,"","
    "],tr:[2,"","
    "],col:[2,"","
    "],td:[3,"","
    "],_default:bK.support.htmlSerialize?[0,"",""]:[1,"X
    ","
    "]},aT=B(l),j=aT.appendChild(l.createElement("div"));U.optgroup=U.option;U.tbody=U.tfoot=U.colgroup=U.caption=U.thead;U.th=U.td;bK.fn.extend({text:function(e){return bK.access(this,function(b4){return b4===aH?bK.text(this):this.empty().append((this[0]&&this[0].ownerDocument||l).createTextNode(b4))},null,e,arguments.length)},wrapAll:function(e){if(bK.isFunction(e)){return this.each(function(b5){bK(this).wrapAll(e.call(this,b5))})}if(this[0]){var b4=bK(e,this[0].ownerDocument).eq(0).clone(true);if(this[0].parentNode){b4.insertBefore(this[0])}b4.map(function(){var b5=this;while(b5.firstChild&&b5.firstChild.nodeType===1){b5=b5.firstChild}return b5}).append(this)}return this},wrapInner:function(e){if(bK.isFunction(e)){return this.each(function(b4){bK(this).wrapInner(e.call(this,b4))})}return this.each(function(){var b4=bK(this),b5=b4.contents();if(b5.length){b5.wrapAll(e)}else{b4.append(e)}})},wrap:function(e){var b4=bK.isFunction(e);return this.each(function(b5){bK(this).wrapAll(b4?e.call(this,b5):e)})},unwrap:function(){return this.parent().each(function(){if(!bK.nodeName(this,"body")){bK(this).replaceWith(this.childNodes)}}).end()},append:function(){return this.domManip(arguments,true,function(e){if(this.nodeType===1||this.nodeType===11||this.nodeType===9){this.appendChild(e)}})},prepend:function(){return this.domManip(arguments,true,function(e){if(this.nodeType===1||this.nodeType===11||this.nodeType===9){this.insertBefore(e,this.firstChild)}})},before:function(){return this.domManip(arguments,false,function(e){if(this.parentNode){this.parentNode.insertBefore(e,this)}})},after:function(){return this.domManip(arguments,false,function(e){if(this.parentNode){this.parentNode.insertBefore(e,this.nextSibling)}})},remove:function(e,b6){var b5,b4=0;for(;(b5=this[b4])!=null;b4++){if(!e||bK.filter(e,[b5]).length>0){if(!b6&&b5.nodeType===1){bK.cleanData(k(b5))}if(b5.parentNode){if(b6&&bK.contains(b5.ownerDocument,b5)){bt(k(b5,"script"))}b5.parentNode.removeChild(b5)}}}return this},empty:function(){var b4,e=0;for(;(b4=this[e])!=null;e++){if(b4.nodeType===1){bK.cleanData(k(b4,false))}while(b4.firstChild){b4.removeChild(b4.firstChild)}if(b4.options&&bK.nodeName(b4,"select")){b4.options.length=0}}return this},clone:function(b4,e){b4=b4==null?false:b4;e=e==null?b4:e;return this.map(function(){return bK.clone(this,b4,e)})},html:function(e){return bK.access(this,function(b7){var b6=this[0]||{},b5=0,b4=this.length;if(b7===aH){return b6.nodeType===1?b6.innerHTML.replace(aB,""):aH}if(typeof b7==="string"&&!am.test(b7)&&(bK.support.htmlSerialize||!K.test(b7))&&(bK.support.leadingWhitespace||!b3.test(b7))&&!U[(m.exec(b7)||["",""])[1].toLowerCase()]){b7=b7.replace(aE,"<$1>");try{for(;b5")){cb=b4.cloneNode(true)}else{j.innerHTML=b4.outerHTML;j.removeChild(cb=j.firstChild)}if((!bK.support.noCloneEvent||!bK.support.noCloneChecked)&&(b4.nodeType===1||b4.nodeType===11)&&!bK.isXMLDoc(b4)){b8=k(cb);b9=k(b4);for(b7=0;(b5=b9[b7])!=null;++b7){if(b8[b7]){R(b5,b8[b7])}}}if(b6){if(e){b9=b9||k(b4);b8=b8||k(cb);for(b7=0;(b5=b9[b7])!=null;b7++){au(b5,b8[b7])}}else{au(b4,cb)}}b8=k(cb,"script");if(b8.length>0){bt(b8,!ca&&k(b4,"script"))}b8=b9=b5=null;return cb},buildFragment:function(b4,b6,cb,cg){var cc,b8,ca,cf,ch,ce,b5,b9=b4.length,b7=B(b6),e=[],cd=0;for(;cd")+b5[2];cc=b5[0];while(cc--){cf=cf.lastChild}if(!bK.support.leadingWhitespace&&b3.test(b8)){e.push(b6.createTextNode(b3.exec(b8)[0]))}if(!bK.support.tbody){b8=ch==="table"&&!bY.test(b8)?cf.firstChild:b5[1]===""&&!bY.test(b8)?cf:0;cc=b8&&b8.childNodes.length;while(cc--){if(bK.nodeName((ce=b8.childNodes[cc]),"tbody")&&!ce.childNodes.length){b8.removeChild(ce)}}}bK.merge(e,cf.childNodes);cf.textContent="";while(cf.firstChild){cf.removeChild(cf.firstChild)}cf=b7.lastChild}}}}if(cf){b7.removeChild(cf)}if(!bK.support.appendChecked){bK.grep(k(e,"input"),bW)}cd=0;while((b8=e[cd++])){if(cg&&bK.inArray(b8,cg)!==-1){continue}ca=bK.contains(b8.ownerDocument,b8);cf=k(b7.appendChild(b8),"script");if(ca){bt(cf)}if(cb){cc=0;while((b8=cf[cc++])){if(bA.test(b8.type||"")){cb.push(b8)}}}}cf=null;return b7},cleanData:function(b4,cc){var b6,cb,b5,b7,b8=0,cd=bK.expando,e=bK.cache,b9=bK.support.deleteExpando,ca=bK.event.special;for(;(b6=b4[b8])!=null;b8++){if(cc||bK.acceptData(b6)){b5=b6[cd];b7=b5&&e[b5];if(b7){if(b7.events){for(cb in b7.events){if(ca[cb]){bK.event.remove(b6,cb)}else{bK.removeEvent(b6,cb,b7.handle)}}}if(e[b5]){delete e[b5];if(b9){delete b6[cd]}else{if(typeof b6.removeAttribute!==aD){b6.removeAttribute(cd)}else{b6[cd]=null}}a7.push(b5)}}}}}});var aF,bp,F,bh=/alpha\([^)]*\)/i,aU=/opacity\s*=\s*([^)]*)/,bo=/^(top|right|bottom|left)$/,G=/^(none|table(?!-c[ea]).+)/,aZ=/^margin/,ba=new RegExp("^("+bB+")(.*)$","i"),X=new RegExp("^("+bB+")(?!px)[a-z%]+$","i"),T=new RegExp("^([+-])=("+bB+")","i"),bk={BODY:"block"},bc={position:"absolute",visibility:"hidden",display:"block"},bD={letterSpacing:0,fontWeight:400},bU=["Top","Right","Bottom","Left"],aw=["Webkit","O","Moz","ms"];function b(b6,b4){if(b4 in b6){return b4}var b7=b4.charAt(0).toUpperCase()+b4.slice(1),e=b4,b5=aw.length;while(b5--){b4=aw[b5]+b7;if(b4 in b6){return b4}}return e}function Q(b4,e){b4=e||b4;return bK.css(b4,"display")==="none"||!bK.contains(b4.ownerDocument,b4)}function p(b9,e){var ca,b7,b8,b4=[],b5=0,b6=b9.length;for(;b51)},show:function(){return p(this,true)},hide:function(){return p(this)},toggle:function(b4){var e=typeof b4==="boolean";return this.each(function(){if(e?b4:Q(this)){bK(this).show()}else{bK(this).hide()}})}});bK.extend({cssHooks:{opacity:{get:function(b5,b4){if(b4){var e=F(b5,"opacity");return e===""?"1":e}}}},cssNumber:{columnCount:true,fillOpacity:true,fontWeight:true,lineHeight:true,opacity:true,orphans:true,widows:true,zIndex:true,zoom:true},cssProps:{"float":bK.support.cssFloat?"cssFloat":"styleFloat"},style:function(b6,b5,cc,b7){if(!b6||b6.nodeType===3||b6.nodeType===8||!b6.style){return}var ca,cb,cd,b8=bK.camelCase(b5),b4=b6.style;b5=bK.cssProps[b8]||(bK.cssProps[b8]=b(b4,b8));cd=bK.cssHooks[b5]||bK.cssHooks[b8];if(cc!==aH){cb=typeof cc;if(cb==="string"&&(ca=T.exec(cc))){cc=(ca[1]+1)*ca[2]+parseFloat(bK.css(b6,b5));cb="number"}if(cc==null||cb==="number"&&isNaN(cc)){return}if(cb==="number"&&!bK.cssNumber[b8]){cc+="px"}if(!bK.support.clearCloneStyle&&cc===""&&b5.indexOf("background")===0){b4[b5]="inherit"}if(!cd||!("set" in cd)||(cc=cd.set(b6,cc,b7))!==aH){try{b4[b5]=cc}catch(b9){}}}else{if(cd&&"get" in cd&&(ca=cd.get(b6,false,b7))!==aH){return ca}return b4[b5]}},css:function(b9,b7,b4,b8){var b6,ca,e,b5=bK.camelCase(b7);b7=bK.cssProps[b5]||(bK.cssProps[b5]=b(b9.style,b5));e=bK.cssHooks[b7]||bK.cssHooks[b5];if(e&&"get" in e){ca=e.get(b9,true,b4)}if(ca===aH){ca=F(b9,b7,b8)}if(ca==="normal"&&b7 in bD){ca=bD[b7]}if(b4===""||b4){b6=parseFloat(ca);return b4===true||bK.isNumeric(b6)?b6||0:ca}return ca},swap:function(b8,b7,b9,b6){var b5,b4,e={};for(b4 in b7){e[b4]=b8.style[b4];b8.style[b4]=b7[b4]}b5=b9.apply(b8,b6||[]);for(b4 in b7){b8.style[b4]=e[b4]}return b5}});if(a3.getComputedStyle){bp=function(e){return a3.getComputedStyle(e,null)};F=function(b7,b5,b9){var b6,b4,cb,b8=b9||bp(b7),ca=b8?b8.getPropertyValue(b5)||b8[b5]:aH,e=b7.style;if(b8){if(ca===""&&!bK.contains(b7.ownerDocument,b7)){ca=bK.style(b7,b5)}if(X.test(ca)&&aZ.test(b5)){b6=e.width;b4=e.minWidth;cb=e.maxWidth;e.minWidth=e.maxWidth=e.width=ca;ca=b8.width;e.width=b6;e.minWidth=b4;e.maxWidth=cb}}return ca}}else{if(l.documentElement.currentStyle){bp=function(e){return e.currentStyle};F=function(b6,b4,b9){var b5,b8,ca,b7=b9||bp(b6),cb=b7?b7[b4]:aH,e=b6.style;if(cb==null&&e&&e[b4]){cb=e[b4]}if(X.test(cb)&&!bo.test(b4)){b5=e.left;b8=b6.runtimeStyle;ca=b8&&b8.left;if(ca){b8.left=b6.currentStyle.left}e.left=b4==="fontSize"?"1em":cb;cb=e.pixelLeft+"px";e.left=b5;if(ca){b8.left=ca}}return cb===""?"auto":cb}}}function aK(e,b5,b6){var b4=ba.exec(b5);return b4?Math.max(0,b4[1]-(b6||0))+(b4[2]||"px"):b5}function ax(b7,b4,e,b9,b6){var b5=e===(b9?"border":"content")?4:b4==="width"?1:0,b8=0;for(;b5<4;b5+=2){if(e==="margin"){b8+=bK.css(b7,e+bU[b5],true,b6)}if(b9){if(e==="content"){b8-=bK.css(b7,"padding"+bU[b5],true,b6)}if(e!=="margin"){b8-=bK.css(b7,"border"+bU[b5]+"Width",true,b6)}}else{b8+=bK.css(b7,"padding"+bU[b5],true,b6);if(e!=="padding"){b8+=bK.css(b7,"border"+bU[b5]+"Width",true,b6)}}}return b8}function v(b7,b4,e){var b6=true,b8=b4==="width"?b7.offsetWidth:b7.offsetHeight,b5=bp(b7),b9=bK.support.boxSizing&&bK.css(b7,"boxSizing",false,b5)==="border-box";if(b8<=0||b8==null){b8=F(b7,b4,b5);if(b8<0||b8==null){b8=b7.style[b4]}if(X.test(b8)){return b8}b6=b9&&(bK.support.boxSizingReliable||b8===b7.style[b4]);b8=parseFloat(b8)||0}return(b8+ax(b7,b4,e||(b9?"border":"content"),b6,b5))+"px"}function bF(b5){var b4=l,e=bk[b5];if(!e){e=a2(b5,b4);if(e==="none"||!e){aF=(aF||bK("