From 7eb2c89f3935a3b7066d46547101f75b9301bd7c Mon Sep 17 00:00:00 2001 From: Dale Visser Date: Sun, 9 Aug 2015 14:34:24 -0400 Subject: [PATCH 1/8] rugygems: Added gemspec test resources, test cases, and minimal code to run tests and have evidence gathering test fail. --- .../analyzer/RubyGemspecAnalyzer.java | 117 ++++++++++++++++++ .../analyzer/RubyGemspecAnalyzerTest.java | 103 +++++++++++++++ .../specifications/mime-types-2.6.1.gemspec | 72 +++++++++++ .../gems/specifications/netrc-0.10.3.gemspec | 32 +++++ .../specifications/rest-client-1.7.2.gemspec | 54 ++++++++ .../owasp/dependencycheck/utils/Settings.java | 4 + 6 files changed, 382 insertions(+) create mode 100644 dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java create mode 100644 dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzerTest.java create mode 100644 dependency-check-core/src/test/resources/ruby/gems/specifications/mime-types-2.6.1.gemspec create mode 100644 dependency-check-core/src/test/resources/ruby/gems/specifications/netrc-0.10.3.gemspec create mode 100644 dependency-check-core/src/test/resources/ruby/gems/specifications/rest-client-1.7.2.gemspec diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java new file mode 100644 index 000000000..8cca141f5 --- /dev/null +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java @@ -0,0 +1,117 @@ +/* + * This file is part of dependency-check-core. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (c) 2015 Institute for Defense Analyses. All Rights Reserved. + */ +package org.owasp.dependencycheck.analyzer; + +import org.apache.commons.io.FileUtils; +import org.owasp.dependencycheck.Engine; +import org.owasp.dependencycheck.analyzer.exception.AnalysisException; +import org.owasp.dependencycheck.dependency.Dependency; +import org.owasp.dependencycheck.utils.FileFilterBuilder; +import org.owasp.dependencycheck.utils.Settings; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.FileFilter; +import java.io.IOException; + +/** + * Used to analyze Node Package Manager (npm) package.json files, and collect information that can be used to determine + * the associated CPE. + * + * @author Dale Visser + */ +public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer { + + /** + * The logger. + */ + private static final Logger LOGGER = LoggerFactory.getLogger(RubyGemspecAnalyzer.class); + + /** + * The name of the analyzer. + */ + private static final String ANALYZER_NAME = "Ruby Gemspec Analyzer"; + + /** + * The phase that this analyzer is intended to run in. + */ + private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION; + + private static final FileFilter FILTER = + FileFilterBuilder.newInstance().addExtensions("gemspec").addFilenames("Rakefile").build(); + + /** + * Returns the FileFilter + * + * @return the FileFilter + */ + @Override + protected FileFilter getFileFilter() { + return FILTER; + } + + @Override + protected void initializeFileTypeAnalyzer() throws Exception { + // NO-OP + } + + /** + * Returns the name of the analyzer. + * + * @return the name of the analyzer. + */ + @Override + public String getName() { + return ANALYZER_NAME; + } + + /** + * Returns the phase that the analyzer is intended to run in. + * + * @return the phase that the analyzer is intended to run in. + */ + @Override + public AnalysisPhase getAnalysisPhase() { + return ANALYSIS_PHASE; + } + + /** + * Returns the key used in the properties file to reference the analyzer's enabled property. + * + * @return the analyzer's enabled property setting key + */ + @Override + protected String getAnalyzerEnabledSettingKey() { + return Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED; + } + + @Override + protected void analyzeFileType(Dependency dependency, Engine engine) + throws AnalysisException { + final File file = dependency.getActualFile(); + String contents; + try { + contents = FileUtils.readFileToString(file).trim(); + } catch (IOException e) { + throw new AnalysisException( + "Problem occurred while reading dependency file.", e); + } + // TODO analyze contents + } +} diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzerTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzerTest.java new file mode 100644 index 000000000..dd749f193 --- /dev/null +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzerTest.java @@ -0,0 +1,103 @@ +/* + * This file is part of dependency-check-core. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (c) 2015 Institute for Defense Analyses. All Rights Reserved. + */ +package org.owasp.dependencycheck.analyzer; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.owasp.dependencycheck.BaseTest; +import org.owasp.dependencycheck.analyzer.exception.AnalysisException; +import org.owasp.dependencycheck.dependency.Dependency; + +import java.io.File; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.*; + +/** + * Unit tests for {@link RubyGemspecAnalyzer}. + * + * @author Dale Visser + */ +public class RubyGemspecAnalyzerTest extends BaseTest { + + /** + * The analyzer to test. + */ + RubyGemspecAnalyzer analyzer; + + /** + * Correctly setup the analyzer for testing. + * + * @throws Exception thrown if there is a problem + */ + @Before + public void setUp() throws Exception { + analyzer = new RubyGemspecAnalyzer(); + analyzer.setFilesMatched(true); + analyzer.initialize(); + } + + /** + * Cleanup the analyzer's temp files, etc. + * + * @throws Exception thrown if there is a problem + */ + @After + public void tearDown() throws Exception { + analyzer.close(); + analyzer = null; + } + + /** + * Test of getName method, of class PythonDistributionAnalyzer. + */ + @Test + public void testGetName() { + assertThat(analyzer.getName(), is("Ruby Gemspec Analyzer")); + } + + /** + * Test of supportsExtension method, of class PythonDistributionAnalyzer. + */ + @Test + public void testSupportsFiles() { + assertThat(analyzer.accept(new File("test.gemspec")), is(true)); + assertThat(analyzer.accept(new File("Rakefile")), is(true)); + } + + /** + * Test of inspect method, of class PythonDistributionAnalyzer. + * + * @throws AnalysisException is thrown when an exception occurs. + */ + @Test + public void testAnalyzePackageJson() throws AnalysisException { + final Dependency result = new Dependency(BaseTest.getResourceAsFile(this, + "ruby/gems/specifications/rest-client-1.7.2.gemspec")); + analyzer.analyze(result, null); + final String vendorString = result.getVendorEvidence().toString(); + assertThat(vendorString, containsString("REST Client Team")); + assertThat(vendorString, containsString("rest-client_project")); + assertThat(vendorString, containsString("rest.client@librelist.com")); + assertThat(vendorString, containsString("https://github.com/rest-client/rest-client")); + assertThat(result.getProductEvidence().toString(), containsString("rest-client")); + assertThat(result.getVersionEvidence().toString(), containsString("1.7.2")); + } +} diff --git a/dependency-check-core/src/test/resources/ruby/gems/specifications/mime-types-2.6.1.gemspec b/dependency-check-core/src/test/resources/ruby/gems/specifications/mime-types-2.6.1.gemspec new file mode 100644 index 000000000..1bea93f2f --- /dev/null +++ b/dependency-check-core/src/test/resources/ruby/gems/specifications/mime-types-2.6.1.gemspec @@ -0,0 +1,72 @@ +# -*- encoding: utf-8 -*- +# stub: mime-types 2.6.1 ruby lib + +Gem::Specification.new do |s| + s.name = "mime-types" + s.version = "2.6.1" + + s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= + s.require_paths = ["lib"] + s.authors = ["Austin Ziegler"] + s.date = "2015-05-25" + s.description = "The mime-types library provides a library and registry for information about\nMIME content type definitions. It can be used to determine defined filename\nextensions for MIME types, or to use filename extensions to look up the likely\nMIME type definitions.\n\nMIME content types are used in MIME-compliant communications, as in e-mail or\nHTTP traffic, to indicate the type of content which is transmitted. The\nmime-types library provides the ability for detailed information about MIME\nentities (provided as an enumerable collection of MIME::Type objects) to be\ndetermined and used. There are many types defined by RFCs and vendors, so the\nlist is long but by definition incomplete; don't hesitate to add additional\ntype definitions. MIME type definitions found in mime-types are from RFCs, W3C\nrecommendations, the {IANA Media Types\nregistry}[https://www.iana.org/assignments/media-types/media-types.xhtml], and\nuser contributions. It conforms to RFCs 2045 and 2231.\n\nThis is release 2.6 with two new experimental features. The first new feature\nis a new default registry storage format that greatly reduces the initial\nmemory use of the mime-types library. This feature is enabled by requiring\n+mime/types/columnar+ instead of +mime/types+ with a small performance cost and\nno change in *total* memory use if certain methods are called (see {Columnar\nStore}[#columnar-store] for more details). The second new feature is a logger\ninterface that conforms to the expectations of an ActiveSupport::Logger so that\nwarnings can be written to an application's log rather than the default\nlocation for +warn+. This interface may be used for other logging purposes in\nthe future.\n\nmime-types 2.6 is the last planned version of mime-types 2.x, so deprecation\nwarnings are no longer cached but provided every time the method is called.\nmime-types 2.6 supports Ruby 1.9.2 or later." + s.email = ["halostatue@gmail.com"] + s.extra_rdoc_files = ["Contributing.rdoc", "History-Types.rdoc", "History.rdoc", "Licence.rdoc", "Manifest.txt", "README.rdoc", "docs/COPYING.txt", "docs/artistic.txt"] + s.files = ["Contributing.rdoc", "History-Types.rdoc", "History.rdoc", "Licence.rdoc", "Manifest.txt", "README.rdoc", "docs/COPYING.txt", "docs/artistic.txt"] + s.homepage = "https://github.com/mime-types/ruby-mime-types/" + s.licenses = ["MIT", "Artistic 2.0", "GPL-2"] + s.rdoc_options = ["--main", "README.rdoc"] + s.required_ruby_version = Gem::Requirement.new(">= 1.9.2") + s.rubygems_version = "2.2.2" + s.summary = "The mime-types library provides a library and registry for information about MIME content type definitions" + + s.installed_by_version = "2.2.2" if s.respond_to? :installed_by_version + + if s.respond_to? :specification_version then + s.specification_version = 4 + + if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then + s.add_development_dependency(%q, ["~> 5.6"]) + s.add_development_dependency(%q, ["~> 4.0"]) + s.add_development_dependency(%q, ["~> 1.0"]) + s.add_development_dependency(%q, ["~> 1.1"]) + s.add_development_dependency(%q, ["~> 1.6"]) + s.add_development_dependency(%q, ["~> 1.0"]) + s.add_development_dependency(%q, ["~> 1.2"]) + s.add_development_dependency(%q, ["~> 1.0"]) + s.add_development_dependency(%q, ["~> 1.0"]) + s.add_development_dependency(%q, ["~> 10.0"]) + s.add_development_dependency(%q, ["~> 0.7"]) + s.add_development_dependency(%q, ["~> 0.8"]) + s.add_development_dependency(%q, ["~> 3.13"]) + else + s.add_dependency(%q, ["~> 5.6"]) + s.add_dependency(%q, ["~> 4.0"]) + s.add_dependency(%q, ["~> 1.0"]) + s.add_dependency(%q, ["~> 1.1"]) + s.add_dependency(%q, ["~> 1.6"]) + s.add_dependency(%q, ["~> 1.0"]) + s.add_dependency(%q, ["~> 1.2"]) + s.add_dependency(%q, ["~> 1.0"]) + s.add_dependency(%q, ["~> 1.0"]) + s.add_dependency(%q, ["~> 10.0"]) + s.add_dependency(%q, ["~> 0.7"]) + s.add_dependency(%q, ["~> 0.8"]) + s.add_dependency(%q, ["~> 3.13"]) + end + else + s.add_dependency(%q, ["~> 5.6"]) + s.add_dependency(%q, ["~> 4.0"]) + s.add_dependency(%q, ["~> 1.0"]) + s.add_dependency(%q, ["~> 1.1"]) + s.add_dependency(%q, ["~> 1.6"]) + s.add_dependency(%q, ["~> 1.0"]) + s.add_dependency(%q, ["~> 1.2"]) + s.add_dependency(%q, ["~> 1.0"]) + s.add_dependency(%q, ["~> 1.0"]) + s.add_dependency(%q, ["~> 10.0"]) + s.add_dependency(%q, ["~> 0.7"]) + s.add_dependency(%q, ["~> 0.8"]) + s.add_dependency(%q, ["~> 3.13"]) + end +end diff --git a/dependency-check-core/src/test/resources/ruby/gems/specifications/netrc-0.10.3.gemspec b/dependency-check-core/src/test/resources/ruby/gems/specifications/netrc-0.10.3.gemspec new file mode 100644 index 000000000..f93212cf0 --- /dev/null +++ b/dependency-check-core/src/test/resources/ruby/gems/specifications/netrc-0.10.3.gemspec @@ -0,0 +1,32 @@ +# -*- encoding: utf-8 -*- +# stub: netrc 0.10.3 ruby lib + +Gem::Specification.new do |s| + s.name = "netrc" + s.version = "0.10.3" + + s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= + s.require_paths = ["lib"] + s.authors = ["Keith Rarick", "geemus (Wesley Beary)"] + s.date = "2015-02-24" + s.description = "This library can read and update netrc files, preserving formatting including comments and whitespace." + s.email = "geemus@gmail.com" + s.homepage = "https://github.com/geemus/netrc" + s.licenses = ["MIT"] + s.rubygems_version = "2.2.2" + s.summary = "Library to read and write netrc files." + + s.installed_by_version = "2.2.2" if s.respond_to? :installed_by_version + + if s.respond_to? :specification_version then + s.specification_version = 4 + + if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then + s.add_development_dependency(%q, [">= 0"]) + else + s.add_dependency(%q, [">= 0"]) + end + else + s.add_dependency(%q, [">= 0"]) + end +end diff --git a/dependency-check-core/src/test/resources/ruby/gems/specifications/rest-client-1.7.2.gemspec b/dependency-check-core/src/test/resources/ruby/gems/specifications/rest-client-1.7.2.gemspec new file mode 100644 index 000000000..b5939feac --- /dev/null +++ b/dependency-check-core/src/test/resources/ruby/gems/specifications/rest-client-1.7.2.gemspec @@ -0,0 +1,54 @@ +# -*- encoding: utf-8 -*- +# stub: rest-client 1.7.2 ruby lib + +Gem::Specification.new do |s| + s.name = "rest-client" + s.version = "1.7.2" + + s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= + s.require_paths = ["lib"] + s.authors = ["REST Client Team"] + s.date = "2014-07-14" + s.description = "A simple HTTP and REST client for Ruby, inspired by the Sinatra microframework style of specifying actions: get, put, post, delete." + s.email = "rest.client@librelist.com" + s.executables = ["restclient"] + s.extra_rdoc_files = ["README.rdoc", "history.md"] + s.files = ["README.rdoc", "bin/restclient", "history.md"] + s.homepage = "https://github.com/rest-client/rest-client" + s.licenses = ["MIT"] + s.required_ruby_version = Gem::Requirement.new(">= 1.9.2") + s.rubygems_version = "2.2.2" + s.summary = "Simple HTTP and REST client for Ruby, inspired by microframework syntax for specifying actions." + + s.installed_by_version = "2.2.2" if s.respond_to? :installed_by_version + + if s.respond_to? :specification_version then + s.specification_version = 3 + + if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then + s.add_development_dependency(%q, ["~> 1.4"]) + s.add_development_dependency(%q, ["~> 2.4"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, ["< 5.0", ">= 2.4.2"]) + s.add_runtime_dependency(%q, ["< 3.0", ">= 1.16"]) + s.add_runtime_dependency(%q, ["~> 0.7"]) + else + s.add_dependency(%q, ["~> 1.4"]) + s.add_dependency(%q, ["~> 2.4"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["< 5.0", ">= 2.4.2"]) + s.add_dependency(%q, ["< 3.0", ">= 1.16"]) + s.add_dependency(%q, ["~> 0.7"]) + end + else + s.add_dependency(%q, ["~> 1.4"]) + s.add_dependency(%q, ["~> 2.4"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["< 5.0", ">= 2.4.2"]) + s.add_dependency(%q, ["< 3.0", ">= 1.16"]) + s.add_dependency(%q, ["~> 0.7"]) + end +end diff --git a/dependency-check-utils/src/main/java/org/owasp/dependencycheck/utils/Settings.java b/dependency-check-utils/src/main/java/org/owasp/dependencycheck/utils/Settings.java index 7cb006aeb..482e19753 100644 --- a/dependency-check-utils/src/main/java/org/owasp/dependencycheck/utils/Settings.java +++ b/dependency-check-utils/src/main/java/org/owasp/dependencycheck/utils/Settings.java @@ -194,6 +194,10 @@ public final class Settings { * The properties key for whether the Python Package analyzer is enabled. */ public static final String ANALYZER_PYTHON_PACKAGE_ENABLED = "analyzer.python.package.enabled"; + /** + * The properties key for whether the Ruby Gemspec Analyzer is enabled. + */ + public static final String ANALYZER_RUBY_GEMSPEC_ENABLED = "analyzer.ruby.gemspec.enabled"; /** * The properties key for whether the Autoconf analyzer is enabled. */ From c0752575c6a9840fb0149f54f64432c5ef36a0c1 Mon Sep 17 00:00:00 2001 From: Dale Visser Date: Sun, 9 Aug 2015 18:57:52 -0400 Subject: [PATCH 2/8] rubygems: All evidence assertions now passing. --- .../analyzer/RubyGemspecAnalyzer.java | 89 +++++++++++++++++-- 1 file changed, 81 insertions(+), 8 deletions(-) diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java index 8cca141f5..27499a1e0 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java @@ -20,15 +20,17 @@ package org.owasp.dependencycheck.analyzer; import org.apache.commons.io.FileUtils; import org.owasp.dependencycheck.Engine; import org.owasp.dependencycheck.analyzer.exception.AnalysisException; +import org.owasp.dependencycheck.dependency.Confidence; import org.owasp.dependencycheck.dependency.Dependency; +import org.owasp.dependencycheck.dependency.EvidenceCollection; import org.owasp.dependencycheck.utils.FileFilterBuilder; import org.owasp.dependencycheck.utils.Settings; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.io.File; import java.io.FileFilter; import java.io.IOException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Used to analyze Node Package Manager (npm) package.json files, and collect information that can be used to determine @@ -38,11 +40,6 @@ import java.io.IOException; */ public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer { - /** - * The logger. - */ - private static final Logger LOGGER = LoggerFactory.getLogger(RubyGemspecAnalyzer.class); - /** * The name of the analyzer. */ @@ -55,6 +52,12 @@ public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer { private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions("gemspec").addFilenames("Rakefile").build(); + public static final String AUTHORS = "authors"; + public static final String NAME = "name"; + public static final String EMAIL = "email"; + public static final String HOMEPAGE = "homepage"; + public static final String GEMSPEC = "gemspec"; + private static final String VERSION = "version"; /** * Returns the FileFilter @@ -101,6 +104,41 @@ public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer { return Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED; } + /** + * Used when compiling file scanning regex patterns. + */ + private static final int REGEX_OPTIONS = Pattern.DOTALL | Pattern.CASE_INSENSITIVE; + + /** + * The capture group #1 is the block variable. + */ + private static final Pattern GEMSPEC_BLOCK_INIT = + Pattern.compile("Gem::Specification\\.new\\s+?do\\s+?\\|(.+?)\\|"); + + /** + * Utility function to create a regex pattern matcher. Group 1 captures the choice of quote character. + * Group 2 captures the string literal. + * + * @param blockVariable the gemspec block variable (usually 's') + * @param field the gemspec field name to capture + * @return the compiled Pattern + */ + private static Pattern compileStringAssignPattern(String blockVariable, String field) { + return Pattern.compile(String.format("\\s+?%s\\.%s\\s*?=\\s*?(['\"])(.*?)\\1", blockVariable, field)); + } + + /** + * Utility function to create a regex pattern matcher. Group 1 captures the list literal. + * + * @param blockVariable the gemspec block variable (usually 's') + * @param field the gemspec field name to capture + */ + private static Pattern compileListAssignPattern(String blockVariable, String field) { + return Pattern.compile( + String.format("\\s+?%s\\.%s\\s*?=\\s*?\\[(.*?)\\]", blockVariable, field), + REGEX_OPTIONS); + } + @Override protected void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { @@ -112,6 +150,41 @@ public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer { throw new AnalysisException( "Problem occurred while reading dependency file.", e); } - // TODO analyze contents + Matcher matcher = GEMSPEC_BLOCK_INIT.matcher(contents); + if (matcher.find()){ + final int startAt = matcher.end(); + final String blockVariable = matcher.group(1); + final EvidenceCollection vendorEvidence = dependency.getVendorEvidence(); + matcher = compileListAssignPattern(blockVariable, AUTHORS).matcher(contents); + if (matcher.find(startAt)) { + final String authors = matcher.group(1).replaceAll("['\"]", " ").trim(); + vendorEvidence.addEvidence(GEMSPEC, AUTHORS, authors, Confidence.HIGHEST); + } + matcher = compileStringAssignPattern(blockVariable, NAME).matcher(contents); + if (matcher.find(startAt)) { + final String name = matcher.group(2); + dependency.getProductEvidence().addEvidence(GEMSPEC, NAME, name, Confidence.HIGHEST); + vendorEvidence.addEvidence(GEMSPEC, "name_project", name + "_project", Confidence.LOW); + } + matcher = compileStringAssignPattern(blockVariable, EMAIL).matcher(contents); + if (matcher.find(startAt)) { + final String email = matcher.group(2); + vendorEvidence.addEvidence(GEMSPEC, EMAIL, email, Confidence.MEDIUM); + } else { + matcher = compileListAssignPattern(blockVariable, EMAIL).matcher(contents); + final String email = matcher.group(1).replaceAll("['\"]", " ").trim(); + vendorEvidence.addEvidence(GEMSPEC, EMAIL, email, Confidence.MEDIUM); + } + matcher = compileStringAssignPattern(blockVariable, HOMEPAGE).matcher(contents); + if (matcher.find(startAt)){ + final String homepage = matcher.group(2); + vendorEvidence.addEvidence(GEMSPEC, HOMEPAGE, homepage, Confidence.MEDIUM); + } + matcher = compileStringAssignPattern(blockVariable, VERSION).matcher(contents); + if (matcher.find(startAt)){ + final String version = matcher.group(2); + dependency.getVersionEvidence().addEvidence(GEMSPEC, VERSION, version, Confidence.HIGHEST); + } + } } } From e7f154b58dd0cc204e8aaf46ebc6f7b3ff1c95b0 Mon Sep 17 00:00:00 2001 From: Dale Visser Date: Sun, 9 Aug 2015 19:34:30 -0400 Subject: [PATCH 3/8] rubygems: Various refactoring improvements. --- .../analyzer/RubyGemspecAnalyzer.java | 100 +++++++----------- 1 file changed, 38 insertions(+), 62 deletions(-) diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java index 27499a1e0..e85677cd5 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java @@ -52,11 +52,11 @@ public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer { private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions("gemspec").addFilenames("Rakefile").build(); - public static final String AUTHORS = "authors"; - public static final String NAME = "name"; - public static final String EMAIL = "email"; - public static final String HOMEPAGE = "homepage"; - public static final String GEMSPEC = "gemspec"; + private static final String AUTHORS = "authors"; + private static final String NAME = "name"; + private static final String EMAIL = "email"; + private static final String HOMEPAGE = "homepage"; + private static final String GEMSPEC = "gemspec"; private static final String VERSION = "version"; /** @@ -104,41 +104,12 @@ public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer { return Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED; } - /** - * Used when compiling file scanning regex patterns. - */ - private static final int REGEX_OPTIONS = Pattern.DOTALL | Pattern.CASE_INSENSITIVE; - /** * The capture group #1 is the block variable. */ private static final Pattern GEMSPEC_BLOCK_INIT = Pattern.compile("Gem::Specification\\.new\\s+?do\\s+?\\|(.+?)\\|"); - /** - * Utility function to create a regex pattern matcher. Group 1 captures the choice of quote character. - * Group 2 captures the string literal. - * - * @param blockVariable the gemspec block variable (usually 's') - * @param field the gemspec field name to capture - * @return the compiled Pattern - */ - private static Pattern compileStringAssignPattern(String blockVariable, String field) { - return Pattern.compile(String.format("\\s+?%s\\.%s\\s*?=\\s*?(['\"])(.*?)\\1", blockVariable, field)); - } - - /** - * Utility function to create a regex pattern matcher. Group 1 captures the list literal. - * - * @param blockVariable the gemspec block variable (usually 's') - * @param field the gemspec field name to capture - */ - private static Pattern compileListAssignPattern(String blockVariable, String field) { - return Pattern.compile( - String.format("\\s+?%s\\.%s\\s*?=\\s*?\\[(.*?)\\]", blockVariable, field), - REGEX_OPTIONS); - } - @Override protected void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { @@ -152,39 +123,44 @@ public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer { } Matcher matcher = GEMSPEC_BLOCK_INIT.matcher(contents); if (matcher.find()){ - final int startAt = matcher.end(); + final int blockStart = matcher.end(); final String blockVariable = matcher.group(1); final EvidenceCollection vendorEvidence = dependency.getVendorEvidence(); - matcher = compileListAssignPattern(blockVariable, AUTHORS).matcher(contents); - if (matcher.find(startAt)) { - final String authors = matcher.group(1).replaceAll("['\"]", " ").trim(); - vendorEvidence.addEvidence(GEMSPEC, AUTHORS, authors, Confidence.HIGHEST); - } - matcher = compileStringAssignPattern(blockVariable, NAME).matcher(contents); - if (matcher.find(startAt)) { - final String name = matcher.group(2); - dependency.getProductEvidence().addEvidence(GEMSPEC, NAME, name, Confidence.HIGHEST); + addListEvidence(vendorEvidence, contents, blockStart, blockVariable, AUTHORS, Confidence.HIGHEST); + String name = addStringEvidence( + dependency.getProductEvidence(), contents, blockStart, blockVariable, NAME, Confidence.HIGHEST); + if (!name.isEmpty()) { vendorEvidence.addEvidence(GEMSPEC, "name_project", name + "_project", Confidence.LOW); } - matcher = compileStringAssignPattern(blockVariable, EMAIL).matcher(contents); - if (matcher.find(startAt)) { - final String email = matcher.group(2); - vendorEvidence.addEvidence(GEMSPEC, EMAIL, email, Confidence.MEDIUM); - } else { - matcher = compileListAssignPattern(blockVariable, EMAIL).matcher(contents); - final String email = matcher.group(1).replaceAll("['\"]", " ").trim(); - vendorEvidence.addEvidence(GEMSPEC, EMAIL, email, Confidence.MEDIUM); - } - matcher = compileStringAssignPattern(blockVariable, HOMEPAGE).matcher(contents); - if (matcher.find(startAt)){ - final String homepage = matcher.group(2); - vendorEvidence.addEvidence(GEMSPEC, HOMEPAGE, homepage, Confidence.MEDIUM); - } - matcher = compileStringAssignPattern(blockVariable, VERSION).matcher(contents); - if (matcher.find(startAt)){ - final String version = matcher.group(2); - dependency.getVersionEvidence().addEvidence(GEMSPEC, VERSION, version, Confidence.HIGHEST); + String email = addStringEvidence(vendorEvidence, contents, blockStart, blockVariable, EMAIL, Confidence.MEDIUM); + if (email.isEmpty()) { + addListEvidence(vendorEvidence, contents, blockStart, blockVariable, EMAIL, Confidence.MEDIUM); } + addStringEvidence(vendorEvidence, contents, blockStart, blockVariable, HOMEPAGE, Confidence.MEDIUM); + addStringEvidence( + dependency.getVersionEvidence(), contents, blockStart, blockVariable, VERSION, Confidence.HIGHEST); } } + + private void addListEvidence(EvidenceCollection vendorEvidence, String contents, int blockStart, + String blockVariable, String field, Confidence confidence) { + final Matcher matcher = Pattern.compile( + String.format("\\s+?%s\\.%s\\s*?=\\s*?\\[(.*?)\\]", blockVariable, field)).matcher(contents); + if (matcher.find(blockStart)) { + final String value = matcher.group(1).replaceAll("['\"]", " ").trim(); + vendorEvidence.addEvidence(GEMSPEC, field, value, confidence); + } + } + + private String addStringEvidence(EvidenceCollection collection, String contents, int blockStart, + String blockVariable, String field, Confidence confidence) { + final Matcher matcher = Pattern.compile( + String.format("\\s+?%s\\.%s\\s*?=\\s*?(['\"])(.*?)\\1", blockVariable, field)).matcher(contents); + String value = ""; + if (matcher.find(blockStart)){ + value = matcher.group(2); + collection.addEvidence(GEMSPEC, field, value, confidence); + } + return value; + } } From 5c02b4dccbac15e0267b17a1977d9868ea43f2fd Mon Sep 17 00:00:00 2001 From: Dale Visser Date: Sun, 9 Aug 2015 19:48:05 -0400 Subject: [PATCH 4/8] rubygems: Added new analyzer to META-INF/services. Confirmed correlation with CPE in CLI. --- .../services/org.owasp.dependencycheck.analyzer.Analyzer | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dependency-check-core/src/main/resources/META-INF/services/org.owasp.dependencycheck.analyzer.Analyzer b/dependency-check-core/src/main/resources/META-INF/services/org.owasp.dependencycheck.analyzer.Analyzer index 84d9863df..659c104b5 100644 --- a/dependency-check-core/src/main/resources/META-INF/services/org.owasp.dependencycheck.analyzer.Analyzer +++ b/dependency-check-core/src/main/resources/META-INF/services/org.owasp.dependencycheck.analyzer.Analyzer @@ -16,4 +16,5 @@ org.owasp.dependencycheck.analyzer.PythonDistributionAnalyzer org.owasp.dependencycheck.analyzer.PythonPackageAnalyzer org.owasp.dependencycheck.analyzer.AutoconfAnalyzer org.owasp.dependencycheck.analyzer.OpenSSLAnalyzer -org.owasp.dependencycheck.analyzer.CMakeAnalyzer \ No newline at end of file +org.owasp.dependencycheck.analyzer.CMakeAnalyzer +org.owasp.dependencycheck.analyzer.RubyGemspecAnalyzer \ No newline at end of file From 2d109b81cff2bcba61557a7059507caf04720094 Mon Sep 17 00:00:00 2001 From: Dale Visser Date: Tue, 11 Aug 2015 13:13:50 -0400 Subject: [PATCH 5/8] rubygems: Used substring(int) to remove the need for Matcher.find(int). Also fixed javadoc, made some variables final, shortened a variable name. --- .../analyzer/RubyGemspecAnalyzer.java | 43 +++++++++---------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java index e85677cd5..a7e0089ad 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java @@ -33,8 +33,8 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; /** - * Used to analyze Node Package Manager (npm) package.json files, and collect information that can be used to determine - * the associated CPE. + * Used to analyze Ruby Gem specifications and collect information that can be used to determine the associated CPE. + * Regular expressions are used to parse the well-defined Ruby syntax that forms the specification. * * @author Dale Visser */ @@ -52,6 +52,7 @@ public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer { private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions("gemspec").addFilenames("Rakefile").build(); + private static final String AUTHORS = "authors"; private static final String NAME = "name"; private static final String EMAIL = "email"; @@ -60,9 +61,7 @@ public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer { private static final String VERSION = "version"; /** - * Returns the FileFilter - * - * @return the FileFilter + * @return a filter that accepts files named Rakefile or matching the glob pattern, *.gemspec */ @Override protected FileFilter getFileFilter() { @@ -113,51 +112,49 @@ public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer { @Override protected void analyzeFileType(Dependency dependency, Engine engine) throws AnalysisException { - final File file = dependency.getActualFile(); String contents; try { - contents = FileUtils.readFileToString(file).trim(); + contents = FileUtils.readFileToString(dependency.getActualFile()); } catch (IOException e) { throw new AnalysisException( "Problem occurred while reading dependency file.", e); } - Matcher matcher = GEMSPEC_BLOCK_INIT.matcher(contents); + final Matcher matcher = GEMSPEC_BLOCK_INIT.matcher(contents); if (matcher.find()){ - final int blockStart = matcher.end(); + contents = contents.substring(matcher.end()); final String blockVariable = matcher.group(1); - final EvidenceCollection vendorEvidence = dependency.getVendorEvidence(); - addListEvidence(vendorEvidence, contents, blockStart, blockVariable, AUTHORS, Confidence.HIGHEST); - String name = addStringEvidence( - dependency.getProductEvidence(), contents, blockStart, blockVariable, NAME, Confidence.HIGHEST); + final EvidenceCollection vendor = dependency.getVendorEvidence(); + addListEvidence(vendor, contents, blockVariable, AUTHORS, Confidence.HIGHEST); + final String name = addStringEvidence( + dependency.getProductEvidence(), contents, blockVariable, NAME, Confidence.HIGHEST); if (!name.isEmpty()) { - vendorEvidence.addEvidence(GEMSPEC, "name_project", name + "_project", Confidence.LOW); + vendor.addEvidence(GEMSPEC, "name_project", name + "_project", Confidence.LOW); } - String email = addStringEvidence(vendorEvidence, contents, blockStart, blockVariable, EMAIL, Confidence.MEDIUM); + final String email = addStringEvidence(vendor, contents, blockVariable, EMAIL, Confidence.MEDIUM); if (email.isEmpty()) { - addListEvidence(vendorEvidence, contents, blockStart, blockVariable, EMAIL, Confidence.MEDIUM); + addListEvidence(vendor, contents, blockVariable, EMAIL, Confidence.MEDIUM); } - addStringEvidence(vendorEvidence, contents, blockStart, blockVariable, HOMEPAGE, Confidence.MEDIUM); - addStringEvidence( - dependency.getVersionEvidence(), contents, blockStart, blockVariable, VERSION, Confidence.HIGHEST); + addStringEvidence(vendor, contents, blockVariable, HOMEPAGE, Confidence.MEDIUM); + addStringEvidence(dependency.getVersionEvidence(), contents, blockVariable, VERSION, Confidence.HIGHEST); } } - private void addListEvidence(EvidenceCollection vendorEvidence, String contents, int blockStart, + private void addListEvidence(EvidenceCollection vendorEvidence, String contents, String blockVariable, String field, Confidence confidence) { final Matcher matcher = Pattern.compile( String.format("\\s+?%s\\.%s\\s*?=\\s*?\\[(.*?)\\]", blockVariable, field)).matcher(contents); - if (matcher.find(blockStart)) { + if (matcher.find()) { final String value = matcher.group(1).replaceAll("['\"]", " ").trim(); vendorEvidence.addEvidence(GEMSPEC, field, value, confidence); } } - private String addStringEvidence(EvidenceCollection collection, String contents, int blockStart, + private String addStringEvidence(EvidenceCollection collection, String contents, String blockVariable, String field, Confidence confidence) { final Matcher matcher = Pattern.compile( String.format("\\s+?%s\\.%s\\s*?=\\s*?(['\"])(.*?)\\1", blockVariable, field)).matcher(contents); String value = ""; - if (matcher.find(blockStart)){ + if (matcher.find()){ value = matcher.group(2); collection.addEvidence(GEMSPEC, field, value, confidence); } From 89166e81fbd92840434936d02bfb9290ca9182a0 Mon Sep 17 00:00:00 2001 From: Dale Visser Date: Tue, 11 Aug 2015 13:48:30 -0400 Subject: [PATCH 6/8] rubygems: Add summary to evidence, inline constants that were only being used once. --- .../analyzer/RubyGemspecAnalyzer.java | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java index a7e0089ad..f657ab393 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java @@ -26,7 +26,6 @@ import org.owasp.dependencycheck.dependency.EvidenceCollection; import org.owasp.dependencycheck.utils.FileFilterBuilder; import org.owasp.dependencycheck.utils.Settings; -import java.io.File; import java.io.FileFilter; import java.io.IOException; import java.util.regex.Matcher; @@ -53,12 +52,8 @@ public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer { private static final FileFilter FILTER = FileFilterBuilder.newInstance().addExtensions("gemspec").addFilenames("Rakefile").build(); - private static final String AUTHORS = "authors"; - private static final String NAME = "name"; private static final String EMAIL = "email"; - private static final String HOMEPAGE = "homepage"; private static final String GEMSPEC = "gemspec"; - private static final String VERSION = "version"; /** * @return a filter that accepts files named Rakefile or matching the glob pattern, *.gemspec @@ -124,18 +119,20 @@ public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer { contents = contents.substring(matcher.end()); final String blockVariable = matcher.group(1); final EvidenceCollection vendor = dependency.getVendorEvidence(); - addListEvidence(vendor, contents, blockVariable, AUTHORS, Confidence.HIGHEST); - final String name = addStringEvidence( - dependency.getProductEvidence(), contents, blockVariable, NAME, Confidence.HIGHEST); - if (!name.isEmpty()) { - vendor.addEvidence(GEMSPEC, "name_project", name + "_project", Confidence.LOW); - } + addStringEvidence(vendor, contents, blockVariable, "author", Confidence.HIGHEST); + addListEvidence(vendor, contents, blockVariable, "authors", Confidence.HIGHEST); final String email = addStringEvidence(vendor, contents, blockVariable, EMAIL, Confidence.MEDIUM); if (email.isEmpty()) { addListEvidence(vendor, contents, blockVariable, EMAIL, Confidence.MEDIUM); } - addStringEvidence(vendor, contents, blockVariable, HOMEPAGE, Confidence.MEDIUM); - addStringEvidence(dependency.getVersionEvidence(), contents, blockVariable, VERSION, Confidence.HIGHEST); + addStringEvidence(vendor, contents, blockVariable, "homepage", Confidence.MEDIUM); + final EvidenceCollection product = dependency.getProductEvidence(); + final String name = addStringEvidence(product, contents, blockVariable, "name", Confidence.HIGHEST); + if (!name.isEmpty()) { + vendor.addEvidence(GEMSPEC, "name_project", name + "_project", Confidence.LOW); + } + addStringEvidence(product, contents, blockVariable, "summary", Confidence.LOW); + addStringEvidence(dependency.getVersionEvidence(), contents, blockVariable, "version", Confidence.HIGHEST); } } From 235869fc79789ec784bf33880e969ea2e203559b Mon Sep 17 00:00:00 2001 From: Dale Visser Date: Tue, 11 Aug 2015 13:56:01 -0400 Subject: [PATCH 7/8] rubygems: Reformat and consisitent parameter naming in private methods. --- .../analyzer/RubyGemspecAnalyzer.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java index f657ab393..5112912e7 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java @@ -115,7 +115,7 @@ public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer { "Problem occurred while reading dependency file.", e); } final Matcher matcher = GEMSPEC_BLOCK_INIT.matcher(contents); - if (matcher.find()){ + if (matcher.find()) { contents = contents.substring(matcher.end()); final String blockVariable = matcher.group(1); final EvidenceCollection vendor = dependency.getVendorEvidence(); @@ -136,24 +136,24 @@ public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer { } } - private void addListEvidence(EvidenceCollection vendorEvidence, String contents, + private void addListEvidence(EvidenceCollection evidences, String contents, String blockVariable, String field, Confidence confidence) { final Matcher matcher = Pattern.compile( String.format("\\s+?%s\\.%s\\s*?=\\s*?\\[(.*?)\\]", blockVariable, field)).matcher(contents); if (matcher.find()) { final String value = matcher.group(1).replaceAll("['\"]", " ").trim(); - vendorEvidence.addEvidence(GEMSPEC, field, value, confidence); + evidences.addEvidence(GEMSPEC, field, value, confidence); } } - private String addStringEvidence(EvidenceCollection collection, String contents, + private String addStringEvidence(EvidenceCollection evidences, String contents, String blockVariable, String field, Confidence confidence) { final Matcher matcher = Pattern.compile( String.format("\\s+?%s\\.%s\\s*?=\\s*?(['\"])(.*?)\\1", blockVariable, field)).matcher(contents); String value = ""; - if (matcher.find()){ + if (matcher.find()) { value = matcher.group(2); - collection.addEvidence(GEMSPEC, field, value, confidence); + evidences.addEvidence(GEMSPEC, field, value, confidence); } return value; } From 88569cb36999b8e5e4ef1fb98f818839167527de Mon Sep 17 00:00:00 2001 From: Dale Visser Date: Tue, 11 Aug 2015 14:23:49 -0400 Subject: [PATCH 8/8] rubygems: Finished command-line interface integration. --- .../main/java/org/owasp/dependencycheck/App.java | 1 + .../java/org/owasp/dependencycheck/CliParser.java | 15 +++++++++++++++ .../src/site/markdown/arguments.md | 1 + 3 files changed, 17 insertions(+) diff --git a/dependency-check-cli/src/main/java/org/owasp/dependencycheck/App.java b/dependency-check-cli/src/main/java/org/owasp/dependencycheck/App.java index ff6dfd27d..648c32cd3 100644 --- a/dependency-check-cli/src/main/java/org/owasp/dependencycheck/App.java +++ b/dependency-check-cli/src/main/java/org/owasp/dependencycheck/App.java @@ -325,6 +325,7 @@ public class App { Settings.setBoolean(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, !nuspecDisabled); Settings.setBoolean(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, !assemblyDisabled); Settings.setBoolean(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, !cli.isOpenSSLDisabled()); + Settings.setBoolean(Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED, !cli.isRubyGemspecDisabled()); Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, !centralDisabled); Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, !nexusDisabled); diff --git a/dependency-check-cli/src/main/java/org/owasp/dependencycheck/CliParser.java b/dependency-check-cli/src/main/java/org/owasp/dependencycheck/CliParser.java index 4f903eede..7101fa389 100644 --- a/dependency-check-cli/src/main/java/org/owasp/dependencycheck/CliParser.java +++ b/dependency-check-cli/src/main/java/org/owasp/dependencycheck/CliParser.java @@ -416,6 +416,8 @@ public final class CliParser { .addOption(disablePythonDistributionAnalyzer) .addOption(disableCmakeAnalyzer) .addOption(disablePythonPackageAnalyzer) + .addOption(OptionBuilder.withLongOpt(ARGUMENT.DISABLE_RUBYGEMS) + .withDescription("Disable the Ruby Gemspec Analyzer.").create()) .addOption(disableAutoconfAnalyzer) .addOption(disableOpenSSLAnalyzer) .addOption(disableNuspecAnalyzer) @@ -543,6 +545,15 @@ public final class CliParser { return (line != null) && line.hasOption(ARGUMENT.DISABLE_PY_PKG); } + /** + * Returns whether the Ruby gemspec analyzer is disabled. + * + * @return true if the {@link ARGUMENT#DISABLE_RUBYGEMS} command line argument was specified; otherwise false + */ + public boolean isRubyGemspecDisabled() { + return (null != line) && line.hasOption(ARGUMENT.DISABLE_RUBYGEMS); + } + /** * Returns true if the disableCmake command line argument was specified. * @@ -1077,6 +1088,10 @@ public final class CliParser { * Disables the Python Package Analyzer. */ public static final String DISABLE_PY_PKG = "disablePyPkg"; + /** + * Disables the Ruby Gemspec Analyzer. + */ + public static final String DISABLE_RUBYGEMS = "disableRubygems"; /** * Disables the Autoconf Analyzer. */ diff --git a/dependency-check-cli/src/site/markdown/arguments.md b/dependency-check-cli/src/site/markdown/arguments.md index 15a1248cc..cd7160a62 100644 --- a/dependency-check-cli/src/site/markdown/arguments.md +++ b/dependency-check-cli/src/site/markdown/arguments.md @@ -30,6 +30,7 @@ Short | Argument Name        | Paramete | \-\-updateonly | | If set only the update phase of dependency-check will be executed; no scan will be executed and no report will be generated. |   | \-\-disablePyDist | | Sets whether the Python Distribution Analyzer will be used. | false | \-\-disablePyPkg | | Sets whether the Python Package Analyzer will be used. | false + | \-\-disableRubygems | | Sets whether the Ruby Gemspec Analyzer will be used. | false | \-\-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