diff --git a/lib/bundler/audit/cli.rb b/lib/bundler/audit/cli.rb index 97979ecc..fd37e136 100644 --- a/lib/bundler/audit/cli.rb +++ b/lib/bundler/audit/cli.rb @@ -73,7 +73,7 @@ def check(dir=Dir.pwd) exit 1 end - report = scanner.report(ignore: options.ignore) + report = scanner.report(ignore: options[:ignore], verbose: options[:verbose]) output = if options[:output] File.new(options[:output],'w') diff --git a/lib/bundler/audit/scanner.rb b/lib/bundler/audit/scanner.rb index f0e79a30..718e51cf 100644 --- a/lib/bundler/audit/scanner.rb +++ b/lib/bundler/audit/scanner.rb @@ -224,11 +224,16 @@ def scan_specs(options={}) config.ignore end + seen = Set.new + @lockfile.specs.each do |gem| @database.check_gem(gem) do |advisory| is_ignored = ignore.intersect?(advisory.identifiers.to_set) next if is_ignored + reportable = options[:verbose] || seen.add?([gem.name, gem.version, advisory.id]) + next unless reportable + yield Results::UnpatchedGem.new(gem,advisory) end end diff --git a/spec/bundle/unpatched_gems/Gemfile.lock b/spec/bundle/unpatched_gems/Gemfile.lock index 81e6b636..94be588c 100644 --- a/spec/bundle/unpatched_gems/Gemfile.lock +++ b/spec/bundle/unpatched_gems/Gemfile.lock @@ -9,6 +9,11 @@ GEM activesupport (= 3.2.10) arel (~> 3.0.2) tzinfo (~> 0.3.29) + activerecord (3.2.10-aarch64-linux-gnu) + activemodel (= 3.2.10) + activesupport (= 3.2.10) + arel (~> 3.0.2) + tzinfo (~> 0.3.29) activesupport (3.2.10) i18n (~> 0.6) multi_json (~> 1.0) @@ -23,6 +28,7 @@ GEM PLATFORMS ruby x86_64-linux + aarch64-linux-gnu DEPENDENCIES activerecord (= 3.2.10) diff --git a/spec/scanner_spec.rb b/spec/scanner_spec.rb index 66f7d6f7..9ee5ac83 100644 --- a/spec/scanner_spec.rb +++ b/spec/scanner_spec.rb @@ -160,6 +160,26 @@ end end + context "when there is more than one platform per gem" do + context "when '--verbose' is passed as an option to the cli" do + subject { super().scan(verbose: true).to_a } + + it "should report one vulnerability per gem regardless of duplications" do + unpatched_gems = subject.map { |r| [r.gem.name, r.gem.version, r.advisory.id] } + expect(unpatched_gems.size).to be > unpatched_gems.uniq.size + end + end + + context "when '--verbose' is not passed as an option to the cli" do + subject { super().scan.to_a } + + it "should deduplicate the report" do + unpatched_gems = subject.map { |r| [r.gem.name, r.gem.version, r.advisory.id] } + expect(unpatched_gems.size).to eq(unpatched_gems.uniq.size) + end + end + end + context "when the :ignore option is given" do subject { super().scan(ignore: ['CVE-2013-0156']) }