diff options
author | Martin Emde <martinemde@users.noreply.github.com> | 2023-08-30 15:15:52 -0700 |
---|---|---|
committer | Hiroshi SHIBATA <hsbt@ruby-lang.org> | 2023-10-23 13:59:01 +0900 |
commit | 92f23a48e3bb7555ca99fc49e15b250a70f9d086 (patch) | |
tree | bd583abe4555696c8b68d141f7f51d8755b2e96e /spec | |
parent | c5fd94073ff2e22b6eea29c242c7e4a12ed7c865 (diff) |
[rubygems/rubygems] Refactor Checksum classes and methods to reduce
code.
(https://github.com/rubygems/rubygems/pull/6917)
https://github.com/rubygems/rubygems/commit/2238bdaadc
Diffstat (limited to 'spec')
-rw-r--r-- | spec/bundler/bundler/definition_spec.rb | 4 | ||||
-rw-r--r-- | spec/bundler/bundler/lockfile_parser_spec.rb | 39 | ||||
-rw-r--r-- | spec/bundler/commands/install_spec.rb | 4 | ||||
-rw-r--r-- | spec/bundler/commands/lock_spec.rb | 68 | ||||
-rw-r--r-- | spec/bundler/commands/update_spec.rb | 4 | ||||
-rw-r--r-- | spec/bundler/install/gemfile/gemspec_spec.rb | 6 | ||||
-rw-r--r-- | spec/bundler/install/gemfile/install_if_spec.rb | 4 | ||||
-rw-r--r-- | spec/bundler/install/gemfile/path_spec.rb | 30 | ||||
-rw-r--r-- | spec/bundler/install/gemfile/platform_spec.rb | 2 | ||||
-rw-r--r-- | spec/bundler/install/gemfile/sources_spec.rb | 16 | ||||
-rw-r--r-- | spec/bundler/install/gemfile/specific_platform_spec.rb | 18 | ||||
-rw-r--r-- | spec/bundler/install/gems/compact_index_spec.rb | 2 | ||||
-rw-r--r-- | spec/bundler/install/yanked_spec.rb | 4 | ||||
-rw-r--r-- | spec/bundler/lock/lockfile_spec.rb | 26 | ||||
-rw-r--r-- | spec/bundler/realworld/edgecases_spec.rb | 7 | ||||
-rw-r--r-- | spec/bundler/support/checksums.rb | 83 |
16 files changed, 192 insertions, 125 deletions
diff --git a/spec/bundler/bundler/definition_spec.rb b/spec/bundler/bundler/definition_spec.rb index ba6f9668ad..64856863ed 100644 --- a/spec/bundler/bundler/definition_spec.rb +++ b/spec/bundler/bundler/definition_spec.rb @@ -78,7 +78,7 @@ RSpec.describe Bundler::Definition do foo! CHECKSUMS - foo (1.0) + #{gem_no_checksum "foo", "1.0"} #{checksum_for_repo_gem gem_repo1, "rack", "1.0.0"} BUNDLED WITH @@ -137,7 +137,7 @@ RSpec.describe Bundler::Definition do foo! CHECKSUMS - foo (1.0) + #{gem_no_checksum "foo", "1.0"} #{checksum_for_repo_gem gem_repo1, "rack", "1.0.0"} BUNDLED WITH diff --git a/spec/bundler/bundler/lockfile_parser_spec.rb b/spec/bundler/bundler/lockfile_parser_spec.rb index 0b8db36324..c05d5a01d1 100644 --- a/spec/bundler/bundler/lockfile_parser_spec.rb +++ b/spec/bundler/bundler/lockfile_parser_spec.rb @@ -22,6 +22,9 @@ RSpec.describe Bundler::LockfileParser do peiji-san! rake + CHECKSUMS + rake (10.3.2) sha256-814828c34f1315d7e7b7e8295184577cc4e969bad6156ac069d02d63f58d82e8 + RUBY VERSION ruby 2.1.3p242 @@ -33,7 +36,7 @@ RSpec.describe Bundler::LockfileParser do it "returns the attributes" do attributes = described_class.sections_in_lockfile(lockfile_contents) expect(attributes).to contain_exactly( - "BUNDLED WITH", "DEPENDENCIES", "GEM", "GIT", "PLATFORMS", "RUBY VERSION" + "BUNDLED WITH", "CHECKSUMS", "DEPENDENCIES", "GEM", "GIT", "PLATFORMS", "RUBY VERSION" ) end end @@ -115,6 +118,7 @@ RSpec.describe Bundler::LockfileParser do let(:platforms) { [rb] } let(:bundler_version) { Gem::Version.new("1.12.0.rc.2") } let(:ruby_version) { "ruby 2.1.3p242" } + let(:lockfile_path) { Bundler.default_lockfile.relative_path_from(Dir.pwd) } shared_examples_for "parsing" do it "parses correctly" do @@ -125,6 +129,11 @@ RSpec.describe Bundler::LockfileParser do expect(subject.platforms).to eq platforms expect(subject.bundler_version).to eq bundler_version expect(subject.ruby_version).to eq ruby_version + checksums = subject.sources.last.checksum_store.checksums("rake-10.3.2") + expect(checksums.size).to eq(1) + expected_checksum = Bundler::Checksum.new("sha256", "814828c34f1315d7e7b7e8295184577cc4e969bad6156ac069d02d63f58d82e8", "#{lockfile_path}:??:1") + expect(checksums.first).to be_match(expected_checksum) + expect(checksums.first.sources.first).to match(/#{Regexp.escape(lockfile_path.to_s)}:\d+:\d+/) end end @@ -149,5 +158,33 @@ RSpec.describe Bundler::LockfileParser do let(:lockfile_contents) { super().sub("peiji-san!", "peiji-san!\n foo: bar") } include_examples "parsing" end + + context "when CHECKSUMS has duplicate checksums that don't match" do + let(:lockfile_contents) { super().split(/(?<=CHECKSUMS\n)/m).insert(1, " rake (10.3.2) sha256-69b69b69b69b69b69b69b69b69b69b69b69b69b69b69b69b69b69b69b69b69b6\n").join } + + it "raises a security error" do + expect { subject }.to raise_error(Bundler::SecurityError) do |e| + expect(e.message).to match <<~MESSAGE + Bundler found multiple different checksums for rake-10.3.2. + This means that there are multiple different `rake-10.3.2.gem` files. + This is a potential security issue, since Bundler could be attempting to install a different gem than what you expect. + + sha256-814828c34f1315d7e7b7e8295184577cc4e969bad6156ac069d02d63f58d82e8 (from #{lockfile_path}:21:1 CHECKSUMS rake (10.3.2)) + sha256-69b69b69b69b69b69b69b69b69b69b69b69b69b69b69b69b69b69b69b69b69b6 from: + * #{lockfile_path}:20:1 CHECKSUMS rake (10.3.2) + + To resolve this issue: + 1. delete any downloaded gems referenced above + 2. run `bundle install` + + If you are sure that the new checksum is correct, you can remove the `rake-10.3.2` entry under the lockfile `CHECKSUMS` section and rerun `bundle install`. + + If you wish to continue installing the downloaded gem, and are certain it does not pose a security issue despite the mismatching checksum, do the following: + 1. run `bundle config set --local disable_checksum_validation true` to turn off checksum verification + 2. run `bundle install` + MESSAGE + end + end + end end end diff --git a/spec/bundler/commands/install_spec.rb b/spec/bundler/commands/install_spec.rb index d6ce92b6d5..aa86d5e316 100644 --- a/spec/bundler/commands/install_spec.rb +++ b/spec/bundler/commands/install_spec.rb @@ -920,7 +920,7 @@ RSpec.describe "bundle install with gem sources" do gem "loofah", "~> 2.12.0" G - checksums = construct_checksum_section do |c| + checksums = checksum_section do |c| c.repo_gem gem_repo4, "crass", "1.0.6" c.repo_gem gem_repo4, "loofah", "2.12.0" c.repo_gem gem_repo4, "nokogiri", "1.12.4", "x86_64-darwin" @@ -964,7 +964,7 @@ RSpec.describe "bundle install with gem sources" do bundle "install", :artifice => "compact_index" end - expected_checksums = construct_checksum_section do |c| + expected_checksums = checksum_section do |c| c.repo_gem gem_repo4, "crass", "1.0.6" c.repo_gem gem_repo4, "loofah", "2.12.0" c.repo_gem gem_repo4, "nokogiri", "1.12.4", "x86_64-darwin" diff --git a/spec/bundler/commands/lock_spec.rb b/spec/bundler/commands/lock_spec.rb index 90138087f6..1e98df75d7 100644 --- a/spec/bundler/commands/lock_spec.rb +++ b/spec/bundler/commands/lock_spec.rb @@ -11,7 +11,7 @@ RSpec.describe "bundle lock" do gem "foo" G - expected_checksums = construct_checksum_section do |c| + expected_checksums = checksum_section do |c| c.repo_gem repo, "actionmailer", "2.3.2" c.repo_gem repo, "actionpack", "2.3.2" c.repo_gem repo, "activerecord", "2.3.2" @@ -67,7 +67,7 @@ RSpec.describe "bundle lock" do # No checksums because no way to get them from a file uri source # + no existing lockfile that has them - expect(out).to eq(@lockfile.strip.gsub(/ sha256-[a-f0-9]+$/, "")) + expect(out).to eq(remove_checksums_from_lockfile(@lockfile.chomp)) end it "prints a lockfile when there is an existing lockfile with --print" do @@ -75,7 +75,7 @@ RSpec.describe "bundle lock" do bundle "lock --print" - expect(out).to eq(@lockfile.strip) + expect(out).to eq(@lockfile.chomp) end it "writes a lockfile when there is no existing lockfile" do @@ -83,7 +83,7 @@ RSpec.describe "bundle lock" do # No checksums because no way to get them from a file uri source # + no existing lockfile that has them - expect(read_lockfile).to eq(@lockfile.gsub(/ sha256-[a-f0-9]+$/, "")) + expect(read_lockfile).to eq(remove_checksums_from_lockfile(@lockfile)) end it "writes a lockfile when there is an outdated lockfile using --update" do @@ -98,7 +98,7 @@ RSpec.describe "bundle lock" do bundle "lock --update", :env => { "BUNDLE_FROZEN" => "true" } # No checksums for the updated gems - expect(read_lockfile).to eq(@lockfile.gsub(/( \(2\.3\.2\)) sha256-[a-f0-9]+$/, "\\1")) + expect(read_lockfile).to eq(remove_checksums_from_lockfile(@lockfile, " (2.3.2)")) end it "does not fetch remote specs when using the --local option" do @@ -125,7 +125,7 @@ RSpec.describe "bundle lock" do foo CHECKSUMS - #{checksum_for_repo_gem repo, "foo", "1.0", :empty => true} + #{gem_no_checksum "foo", "1.0"} BUNDLED WITH #{Bundler::VERSION} @@ -141,7 +141,7 @@ RSpec.describe "bundle lock" do bundle "lock --lockfile=lock" expect(out).to match(/Writing lockfile to.+lock/) - expect(read_lockfile("lock")).to eq(@lockfile.gsub(/ sha256-[a-f0-9]+$/, "")) + expect(read_lockfile("lock")).to eq(remove_checksums_from_lockfile(@lockfile)) expect { read_lockfile }.to raise_error(Errno::ENOENT) end @@ -149,7 +149,7 @@ RSpec.describe "bundle lock" do bundle "install" bundle "lock --lockfile=lock" - expected_checksums = construct_checksum_section do |c| + expected_checksums = checksum_section do |c| c.repo_gem repo, "actionmailer", "2.3.2" c.repo_gem repo, "actionpack", "2.3.2" c.repo_gem repo, "activerecord", "2.3.2" @@ -208,7 +208,7 @@ RSpec.describe "bundle lock" do bundle "lock --update rails rake" - expect(read_lockfile).to eq(@lockfile.gsub(/( \((?:2\.3\.2|13\.0\.1)\)) sha256-[a-f0-9]+$/, "\\1")) + expect(read_lockfile).to eq(remove_checksums_from_lockfile(@lockfile, "(2.3.2)", "(13.0.1)")) end it "preserves unknown checksum algorithms" do @@ -626,10 +626,10 @@ RSpec.describe "bundle lock" do mixlib-shellout CHECKSUMS - #{checksum_for_repo_gem gem_repo4, "ffi", "1.9.14", "x86-mingw32", :empty => true} - #{checksum_for_repo_gem gem_repo4, "gssapi", "1.2.0", :empty => true} - #{checksum_for_repo_gem gem_repo4, "mixlib-shellout", "2.2.6", "universal-mingw32", :empty => true} - #{checksum_for_repo_gem gem_repo4, "win32-process", "0.8.3", :empty => true} + #{gem_no_checksum "ffi", "1.9.14", "x86-mingw32"} + #{gem_no_checksum "gssapi", "1.2.0"} + #{gem_no_checksum "mixlib-shellout", "2.2.6", "universal-mingw32"} + #{gem_no_checksum "win32-process", "0.8.3"} BUNDLED WITH #{Bundler::VERSION} @@ -661,12 +661,12 @@ RSpec.describe "bundle lock" do mixlib-shellout CHECKSUMS - #{checksum_for_repo_gem gem_repo4, "ffi", "1.9.14", :empty => true} - #{checksum_for_repo_gem gem_repo4, "ffi", "1.9.14", "x86-mingw32", :empty => true} - #{checksum_for_repo_gem gem_repo4, "gssapi", "1.2.0", :empty => true} - #{checksum_for_repo_gem gem_repo4, "mixlib-shellout", "2.2.6", :empty => true} - #{checksum_for_repo_gem gem_repo4, "mixlib-shellout", "2.2.6", "universal-mingw32", :empty => true} - #{checksum_for_repo_gem gem_repo4, "win32-process", "0.8.3", :empty => true} + #{gem_no_checksum "ffi", "1.9.14"} + #{gem_no_checksum "ffi", "1.9.14", "x86-mingw32"} + #{gem_no_checksum "gssapi", "1.2.0"} + #{gem_no_checksum "mixlib-shellout", "2.2.6"} + #{gem_no_checksum "mixlib-shellout", "2.2.6", "universal-mingw32"} + #{gem_no_checksum "win32-process", "0.8.3"} BUNDLED WITH #{Bundler::VERSION} @@ -747,8 +747,8 @@ RSpec.describe "bundle lock" do libv8 CHECKSUMS - #{checksum_for_repo_gem gem_repo4, "libv8", "8.4.255.0", "x86_64-darwin-19", :empty => true} - #{checksum_for_repo_gem gem_repo4, "libv8", "8.4.255.0", "x86_64-darwin-20", :empty => true} + #{gem_no_checksum "libv8", "8.4.255.0", "x86_64-darwin-19"} + #{gem_no_checksum "libv8", "8.4.255.0", "x86_64-darwin-20"} BUNDLED WITH #{Bundler::VERSION} @@ -957,7 +957,7 @@ RSpec.describe "bundle lock" do it "does not implicitly update" do bundle "lock" - expected_checksums = construct_checksum_section do |c| + expected_checksums = checksum_section do |c| c.repo_gem repo, "actionmailer", "2.3.2" c.repo_gem repo, "actionpack", "2.3.2" c.repo_gem repo, "activerecord", "2.3.2" @@ -1014,15 +1014,13 @@ RSpec.describe "bundle lock" do gemfile gemfile.gsub('"foo"', '"foo", "2.0"') bundle "lock" - expected_checksums = construct_checksum_section do |c| + expected_checksums = checksum_section do |c| c.repo_gem repo, "actionmailer", "2.3.2" c.repo_gem repo, "actionpack", "2.3.2" c.repo_gem repo, "activerecord", "2.3.2" c.repo_gem repo, "activeresource", "2.3.2" c.repo_gem repo, "activesupport", "2.3.2" - # We don't have a checksum for foo 2, - # since it is not downloaded by bundle lock, therefore we don't include it - # c.repo_gem repo, "foo", "2.0" + c.no_checksum "foo", "2.0" c.repo_gem repo, "rails", "2.3.2" c.repo_gem repo, "rake", "13.0.1" c.repo_gem repo, "weakling", "0.0.3" @@ -1060,7 +1058,7 @@ RSpec.describe "bundle lock" do weakling CHECKSUMS - #{expected_checksums.prepend(" ").lines(:chomp => true).append(" foo (2.0)").sort.join("\n")} + #{expected_checksums} BUNDLED WITH #{Bundler::VERSION} @@ -1137,8 +1135,8 @@ RSpec.describe "bundle lock" do debug CHECKSUMS - #{checksum_for_repo_gem gem_repo4, "debug", "1.6.3", :empty => true} - #{checksum_for_repo_gem gem_repo4, "irb", "1.5.0", :empty => true} + #{gem_no_checksum "debug", "1.6.3"} + #{gem_no_checksum "irb", "1.5.0"} BUNDLED WITH #{Bundler::VERSION} @@ -1444,8 +1442,8 @@ RSpec.describe "bundle lock" do foo! CHECKSUMS - #{checksum_for_repo_gem(gem_repo4, "foo", "1.0", :empty => true)} - #{checksum_for_repo_gem(gem_repo4, "nokogiri", "1.14.2", :empty => true)} + #{gem_no_checksum "foo", "1.0"} + #{gem_no_checksum "nokogiri", "1.14.2"} BUNDLED WITH #{Bundler::VERSION} @@ -1531,10 +1529,10 @@ RSpec.describe "bundle lock" do govuk_app_config CHECKSUMS - #{checksum_for_repo_gem gem_repo4, "actionpack", "7.0.4.3", :empty => true} - #{checksum_for_repo_gem gem_repo4, "activesupport", "7.0.4.3", :empty => true} - #{checksum_for_repo_gem gem_repo4, "govuk_app_config", "4.13.0", :empty => true} - #{checksum_for_repo_gem gem_repo4, "railties", "7.0.4.3", :empty => true} + #{gem_no_checksum "actionpack", "7.0.4.3"} + #{gem_no_checksum "activesupport", "7.0.4.3"} + #{gem_no_checksum "govuk_app_config", "4.13.0"} + #{gem_no_checksum "railties", "7.0.4.3"} BUNDLED WITH #{Bundler::VERSION} diff --git a/spec/bundler/commands/update_spec.rb b/spec/bundler/commands/update_spec.rb index 99ae3e8d07..b1043ae71b 100644 --- a/spec/bundler/commands/update_spec.rb +++ b/spec/bundler/commands/update_spec.rb @@ -509,7 +509,7 @@ RSpec.describe "bundle update" do original_lockfile = lockfile - expected_checksums = construct_checksum_section do |c| + expected_checksums = checksum_section do |c| c.repo_gem gem_repo4, "activesupport", "6.0.4.1" c.repo_gem gem_repo4, "tzinfo", "1.2.9" end @@ -541,7 +541,7 @@ RSpec.describe "bundle update" do # needed because regressing to versions already present on the system # won't add a checksum - expected_lockfile = expected_lockfile.gsub(/ sha256-[a-f0-9]+$/, "") + expected_lockfile = remove_checksums_from_lockfile(expected_lockfile) lockfile original_lockfile bundle "update" diff --git a/spec/bundler/install/gemfile/gemspec_spec.rb b/spec/bundler/install/gemfile/gemspec_spec.rb index da8b6a90b1..f1e68bbec1 100644 --- a/spec/bundler/install/gemfile/gemspec_spec.rb +++ b/spec/bundler/install/gemfile/gemspec_spec.rb @@ -449,7 +449,7 @@ RSpec.describe "bundle install from an existing gemspec" do it "keeps all platform dependencies in the lockfile" do expect(the_bundle).to include_gems "foo 1.0", "platform_specific 1.0 RUBY" - expected_checksums = construct_checksum_section do |c| + expected_checksums = checksum_section do |c| c.repo_gem gem_repo2, "platform_specific", "1.0" c.repo_gem gem_repo2, "platform_specific", "1.0", "java" c.repo_gem gem_repo2, "platform_specific", "1.0", x64_mingw32 @@ -493,7 +493,7 @@ RSpec.describe "bundle install from an existing gemspec" do it "keeps all platform dependencies in the lockfile" do expect(the_bundle).to include_gems "foo 1.0", "platform_specific 1.0 RUBY" - expected_checksums = construct_checksum_section do |c| + expected_checksums = checksum_section do |c| c.repo_gem gem_repo2, "platform_specific", "1.0" c.repo_gem gem_repo2, "platform_specific", "1.0", "java" c.repo_gem gem_repo2, "platform_specific", "1.0", x64_mingw32 @@ -538,7 +538,7 @@ RSpec.describe "bundle install from an existing gemspec" do it "keeps all platform dependencies in the lockfile" do expect(the_bundle).to include_gems "foo 1.0", "indirect_platform_specific 1.0", "platform_specific 1.0 RUBY" - expected_checksums = construct_checksum_section do |c| + expected_checksums = checksum_section do |c| c.repo_gem gem_repo2, "indirect_platform_specific", "1.0" c.repo_gem gem_repo2, "platform_specific", "1.0" c.repo_gem gem_repo2, "platform_specific", "1.0", "java" diff --git a/spec/bundler/install/gemfile/install_if_spec.rb b/spec/bundler/install/gemfile/install_if_spec.rb index ced6f42d79..c8ddb685ff 100644 --- a/spec/bundler/install/gemfile/install_if_spec.rb +++ b/spec/bundler/install/gemfile/install_if_spec.rb @@ -39,9 +39,9 @@ RSpec.describe "bundle install with install_if conditionals" do CHECKSUMS #{checksum_for_repo_gem gem_repo1, "activesupport", "2.3.5"} - #{checksum_for_repo_gem gem_repo1, "foo", "1.0", :empty => true} + #{gem_no_checksum "foo", "1.0"} #{checksum_for_repo_gem gem_repo1, "rack", "1.0.0"} - #{checksum_for_repo_gem gem_repo1, "thin", "1.0", :empty => true} + #{gem_no_checksum "thin", "1.0"} BUNDLED WITH #{Bundler::VERSION} diff --git a/spec/bundler/install/gemfile/path_spec.rb b/spec/bundler/install/gemfile/path_spec.rb index 5d0c759f4e..3af8412eab 100644 --- a/spec/bundler/install/gemfile/path_spec.rb +++ b/spec/bundler/install/gemfile/path_spec.rb @@ -121,8 +121,8 @@ RSpec.describe "bundle install with explicit source paths" do demo! CHECKSUMS - aaa (1.0) - demo (1.0) + #{gem_no_checksum("aaa", "1.0")} + #{gem_no_checksum("demo", "1.0")} BUNDLED WITH #{Bundler::VERSION} @@ -364,8 +364,8 @@ RSpec.describe "bundle install with explicit source paths" do foo! CHECKSUMS - foo (0.1.0) - #{checksum_for_repo_gem gem_repo4, "graphql", "2.0.15"} + #{gem_no_checksum("foo", "0.1.0")} + #{checksum_for_repo_gem(gem_repo4, "graphql", "2.0.15")} BUNDLED WITH #{Bundler::VERSION} @@ -692,8 +692,8 @@ RSpec.describe "bundle install with explicit source paths" do foo! CHECKSUMS - foo (1.0) - #{checksum_for_repo_gem gem_repo1, "rack", "0.9.1"} + #{gem_no_checksum("foo", "1.0")} + #{checksum_for_repo_gem(gem_repo1, "rack", "0.9.1")} BUNDLED WITH #{Bundler::VERSION} @@ -724,8 +724,8 @@ RSpec.describe "bundle install with explicit source paths" do foo! CHECKSUMS - foo (1.0) - #{checksum_for_repo_gem gem_repo1, "rack", "0.9.1"} + #{gem_no_checksum("foo", "1.0")} + #{checksum_for_repo_gem(gem_repo1, "rack", "0.9.1")} BUNDLED WITH #{Bundler::VERSION} @@ -762,8 +762,8 @@ RSpec.describe "bundle install with explicit source paths" do foo! CHECKSUMS - foo (1.0) - #{checksum_for_repo_gem gem_repo1, "rack", "0.9.1"} + #{gem_no_checksum("foo", "1.0")} + #{checksum_for_repo_gem(gem_repo1, "rack", "0.9.1")} BUNDLED WITH #{Bundler::VERSION} @@ -797,9 +797,9 @@ RSpec.describe "bundle install with explicit source paths" do foo! CHECKSUMS - foo (1.0) - #{checksum_for_repo_gem gem_repo1, "rack", "0.9.1"} - #{checksum_for_repo_gem gem_repo1, "rake", "13.0.1"} + #{gem_no_checksum("foo", "1.0")} + #{checksum_for_repo_gem(gem_repo1, "rack", "0.9.1")} + #{checksum_for_repo_gem(gem_repo1, "rake", "13.0.1")} BUNDLED WITH #{Bundler::VERSION} @@ -850,8 +850,8 @@ RSpec.describe "bundle install with explicit source paths" do foo! CHECKSUMS - foo (1.0) - rack (0.9.1) + #{gem_no_checksum("foo", "1.0")} + #{gem_no_checksum("rack", "0.9.1")} BUNDLED WITH #{Bundler::VERSION} diff --git a/spec/bundler/install/gemfile/platform_spec.rb b/spec/bundler/install/gemfile/platform_spec.rb index bb62558deb..918a49e1e1 100644 --- a/spec/bundler/install/gemfile/platform_spec.rb +++ b/spec/bundler/install/gemfile/platform_spec.rb @@ -426,7 +426,7 @@ RSpec.describe "bundle install across platforms" do CHECKSUMS #{checksum_for_repo_gem(gem_repo1, "platform_specific", "1.0")} - #{checksum_for_repo_gem(gem_repo1, "platform_specific", "1.0", "java", :empty => true)} + #{gem_no_checksum "platform_specific", "1.0", "java"} BUNDLED WITH #{Bundler::VERSION} diff --git a/spec/bundler/install/gemfile/sources_spec.rb b/spec/bundler/install/gemfile/sources_spec.rb index 318b4907df..72658aebd9 100644 --- a/spec/bundler/install/gemfile/sources_spec.rb +++ b/spec/bundler/install/gemfile/sources_spec.rb @@ -284,7 +284,7 @@ RSpec.describe "bundle install with gems on multiple sources" do expect(err).to include("Warning: the gem 'rack' was found in multiple sources.") expect(err).to include("Installed from: https://gem.repo2") - expected_checksums = construct_checksum_section do |c| + expected_checksums = checksum_section do |c| c.repo_gem gem_repo3, "depends_on_rack", "1.0.1" c.repo_gem gem_repo2, "rack", "1.0.0" end @@ -706,7 +706,7 @@ RSpec.describe "bundle install with gems on multiple sources" do expect(the_bundle).to include_gems("concurrent-ruby 1.1.8") expect(the_bundle).not_to include_gems("concurrent-ruby 1.1.9") - expected_checksums = construct_checksum_section do |c| + expected_checksums = checksum_section do |c| c.repo_gem gem_repo2, "activesupport", "6.0.3.4" c.repo_gem gem_repo2, "concurrent-ruby", "1.1.8" c.repo_gem gem_repo2, "connection_pool", "2.2.3" @@ -809,7 +809,7 @@ RSpec.describe "bundle install with gems on multiple sources" do expect(the_bundle).not_to include_gems("concurrent-ruby 1.1.8") expect(the_bundle).to include_gems("concurrent-ruby 1.1.9") - expected_checksums = construct_checksum_section do |c| + expected_checksums = checksum_section do |c| c.repo_gem gem_repo2, "activesupport", "6.1.2.1" c.repo_gem gem_repo2, "concurrent-ruby", "1.1.9" c.repo_gem gem_repo2, "connection_pool", "2.2.3" @@ -881,7 +881,7 @@ RSpec.describe "bundle install with gems on multiple sources" do expect(the_bundle).to include_gems("concurrent-ruby 1.1.9") expect(the_bundle).not_to include_gems("concurrent-ruby 1.1.8") - expected_checksums = construct_checksum_section do |c| + expected_checksums = checksum_section do |c| c.repo_gem gem_repo2, "activesupport", "6.0.3.4" c.repo_gem gem_repo2, "concurrent-ruby", "1.1.9" c.repo_gem gem_repo2, "connection_pool", "2.2.3" @@ -1006,7 +1006,7 @@ RSpec.describe "bundle install with gems on multiple sources" do end it "installs from the default source without any warnings or errors and generates a proper lockfile" do - expected_checksums = construct_checksum_section do |c| + expected_checksums = checksum_section do |c| c.repo_gem gem_repo3, "handsoap", "0.2.5.5" c.repo_gem gem_repo2, "nokogiri", "1.11.1" c.repo_gem gem_repo2, "racca", "1.5.2" @@ -1567,7 +1567,7 @@ RSpec.describe "bundle install with gems on multiple sources" do it "upgrades the lockfile correctly" do bundle "lock --update", :artifice => "compact_index" - expected_checksums = construct_checksum_section do |c| + expected_checksums = checksum_section do |c| c.repo_gem gem_repo2, "capybara", "2.5.0" c.repo_gem gem_repo4, "mime-types", "3.0.0" end @@ -1686,7 +1686,7 @@ RSpec.describe "bundle install with gems on multiple sources" do it "handles that fine" do bundle "install", :artifice => "compact_index_extra", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } - expected_checksums = construct_checksum_section do |c| + expected_checksums = checksum_section do |c| c.repo_gem gem_repo4, "pdf-writer", "1.1.8" c.repo_gem gem_repo2, "ruport", "1.7.0.3" end @@ -1741,7 +1741,7 @@ RSpec.describe "bundle install with gems on multiple sources" do it "handles that fine" do bundle "install --verbose", :artifice => "endpoint", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } - expected_checksums = construct_checksum_section do |c| + expected_checksums = checksum_section do |c| c.repo_gem gem_repo4, "pdf-writer", "1.1.8" end diff --git a/spec/bundler/install/gemfile/specific_platform_spec.rb b/spec/bundler/install/gemfile/specific_platform_spec.rb index 6ec236b0c8..cb6b18cda2 100644 --- a/spec/bundler/install/gemfile/specific_platform_spec.rb +++ b/spec/bundler/install/gemfile/specific_platform_spec.rb @@ -528,7 +528,7 @@ RSpec.describe "bundle install with specific platforms" do bundle "update" - expected_checksums = construct_checksum_section do |c| + expected_checksums = checksum_section do |c| c.repo_gem gem_repo4, "sorbet", "0.5.10160" c.repo_gem gem_repo4, "sorbet-runtime", "0.5.10160" c.repo_gem gem_repo4, "sorbet-static", "0.5.10160", Gem::Platform.local @@ -626,8 +626,8 @@ RSpec.describe "bundle install with specific platforms" do sorbet-static CHECKSUMS - #{checksum_for_repo_gem gem_repo4, "nokogiri", "1.13.0", "x86_64-darwin", :empty => true} - #{checksum_for_repo_gem gem_repo4, "sorbet-static", "0.5.10601", "x86_64-darwin", :empty => true} + #{gem_no_checksum "nokogiri", "1.13.0", "x86_64-darwin"} + #{gem_no_checksum "sorbet-static", "0.5.10601", "x86_64-darwin"} BUNDLED WITH #{Bundler::VERSION} @@ -682,7 +682,7 @@ RSpec.describe "bundle install with specific platforms" do bundle "update" - expected_checksums = construct_checksum_section do |c| + expected_checksums = checksum_section do |c| c.repo_gem gem_repo4, "sorbet", "0.5.10160" c.repo_gem gem_repo4, "sorbet-runtime", "0.5.10160" c.repo_gem gem_repo4, "sorbet-static", "0.5.10160", Gem::Platform.local @@ -836,7 +836,7 @@ RSpec.describe "bundle install with specific platforms" do CHECKSUMS #{checksum_for_repo_gem gem_repo4, "sorbet-static", "0.5.10549", "universal-darwin-20"} - #{checksum_for_repo_gem gem_repo4, "sorbet-static", "0.5.10549", "universal-darwin-21", :empty => true} + #{gem_no_checksum "sorbet-static", "0.5.10549", "universal-darwin-21"} BUNDLED WITH #{Bundler::VERSION} @@ -899,8 +899,8 @@ RSpec.describe "bundle install with specific platforms" do tzinfo (~> 1.2) CHECKSUMS - #{checksum_for_repo_gem gem_repo4, "nokogiri", "1.13.8", :empty => true} - #{checksum_for_repo_gem gem_repo4, "nokogiri", "1.13.8", Gem::Platform.local, :empty => true} + #{gem_no_checksum "nokogiri", "1.13.8"} + #{gem_no_checksum "nokogiri", "1.13.8", Gem::Platform.local} BUNDLED WITH #{Bundler::VERSION} @@ -955,8 +955,8 @@ RSpec.describe "bundle install with specific platforms" do rack CHECKSUMS - #{checksum_for_repo_gem gem_repo4, "concurrent-ruby", "1.2.2", :empty => true} - #{checksum_for_repo_gem gem_repo4, "rack", "3.0.7", :empty => true} + #{gem_no_checksum "concurrent-ruby", "1.2.2"} + #{gem_no_checksum "rack", "3.0.7"} BUNDLED WITH #{Bundler::VERSION} diff --git a/spec/bundler/install/gems/compact_index_spec.rb b/spec/bundler/install/gems/compact_index_spec.rb index f723c0da73..4a345824ce 100644 --- a/spec/bundler/install/gems/compact_index_spec.rb +++ b/spec/bundler/install/gems/compact_index_spec.rb @@ -882,7 +882,7 @@ The checksum of /versions does not match the checksum provided by the server! So gem "rack" G - api_checksum = Spec::Checksums::ChecksumsBuilder.new.repo_gem(gem_repo1, "rack", "1.0.0").first.checksums.fetch("sha256") + api_checksum = checksum_for_repo_gem(gem_repo1, "rack", "1.0.0").split("sha256-").last gem_path = if Bundler.feature_flag.global_gem_cache? default_cache_path.dirname.join("cache", "gems", "localgemserver.test.80.dd34752a738ee965a2a4298dc16db6c5", "rack-1.0.0.gem") diff --git a/spec/bundler/install/yanked_spec.rb b/spec/bundler/install/yanked_spec.rb index a84772fa78..338a187472 100644 --- a/spec/bundler/install/yanked_spec.rb +++ b/spec/bundler/install/yanked_spec.rb @@ -161,8 +161,8 @@ RSpec.context "when resolving a bundle that includes yanked gems, but unlocking foo CHECKSUMS - #{checksum_for_repo_gem(gem_repo4, "bar", "2.0.0", :empty => true)} - #{checksum_for_repo_gem(gem_repo4, "foo", "9.0.0", :empty => true)} + #{gem_no_checksum "bar", "2.0.0"} + #{gem_no_checksum "foo", "9.0.0"} BUNDLED WITH #{Bundler::VERSION} diff --git a/spec/bundler/lock/lockfile_spec.rb b/spec/bundler/lock/lockfile_spec.rb index 04355792ef..bab0d915ab 100644 --- a/spec/bundler/lock/lockfile_spec.rb +++ b/spec/bundler/lock/lockfile_spec.rb @@ -279,7 +279,7 @@ RSpec.describe "the lockfile format" do gem "rack-obama" G - expected_checksums = construct_checksum_section do |c| + expected_checksums = checksum_section do |c| c.repo_gem gem_repo2, "rack", "1.0.0" c.repo_gem gem_repo2, "rack-obama", "1.0" end @@ -313,7 +313,7 @@ RSpec.describe "the lockfile format" do gem "rack-obama", ">= 1.0" G - expected_checksums = construct_checksum_section do |c| + expected_checksums = checksum_section do |c| c.repo_gem gem_repo2, "rack", "1.0.0" c.repo_gem gem_repo2, "rack-obama", "1.0" end @@ -355,7 +355,7 @@ RSpec.describe "the lockfile format" do end G - expected_checksums = construct_checksum_section do |c| + expected_checksums = checksum_section do |c| c.repo_gem gem_repo2, "rack", "1.0.0" c.repo_gem gem_repo2, "rack-obama", "1.0" end @@ -396,7 +396,7 @@ RSpec.describe "the lockfile format" do gem "net-sftp" G - expected_checksums = construct_checksum_section do |c| + expected_checksums = checksum_section do |c| c.repo_gem gem_repo2, "net-sftp", "1.1.1" c.repo_gem gem_repo2, "net-ssh", "1.0" end @@ -684,8 +684,8 @@ RSpec.describe "the lockfile format" do ckeditor! CHECKSUMS - #{checksum_for_repo_gem(gem_repo4, "ckeditor", "4.0.8", :empty => true)} - #{checksum_for_repo_gem(gem_repo4, "orm_adapter", "0.4.1", :empty => true)} + #{gem_no_checksum "ckeditor", "4.0.8"} + #{gem_no_checksum "orm_adapter", "0.4.1"} BUNDLED WITH #{Bundler::VERSION} @@ -814,7 +814,7 @@ RSpec.describe "the lockfile format" do gem "rack", :source => "#{file_uri_for(gem_repo2)}/" G - expected_checksums = construct_checksum_section do |c| + expected_checksums = checksum_section do |c| c.repo_gem gem_repo2, "rack", "1.0.0" end @@ -847,7 +847,7 @@ RSpec.describe "the lockfile format" do gem "rack-obama" G - expected_checksums = construct_checksum_section do |c| + expected_checksums = checksum_section do |c| c.repo_gem gem_repo2, "actionpack", "2.3.2" c.repo_gem gem_repo2, "activesupport", "2.3.2" c.repo_gem gem_repo2, "rack", "1.0.0" @@ -891,7 +891,7 @@ RSpec.describe "the lockfile format" do gem "rails" G - expected_checksums = construct_checksum_section do |c| + expected_checksums = checksum_section do |c| c.repo_gem gem_repo2, "actionmailer", "2.3.2" c.repo_gem gem_repo2, "actionpack", "2.3.2" c.repo_gem gem_repo2, "activerecord", "2.3.2" @@ -952,7 +952,7 @@ RSpec.describe "the lockfile format" do gem 'double_deps' G - expected_checksums = construct_checksum_section do |c| + expected_checksums = checksum_section do |c| c.repo_gem gem_repo2, "double_deps", "1.0" c.repo_gem gem_repo2, "net-ssh", "1.0" end @@ -987,7 +987,7 @@ RSpec.describe "the lockfile format" do gem "rack-obama", ">= 1.0", :require => "rack/obama" G - expected_checksums = construct_checksum_section do |c| + expected_checksums = checksum_section do |c| c.repo_gem gem_repo2, "rack", "1.0.0" c.repo_gem gem_repo2, "rack-obama", "1.0" end @@ -1021,7 +1021,7 @@ RSpec.describe "the lockfile format" do gem "rack-obama", ">= 1.0", :group => :test G - expected_checksums = construct_checksum_section do |c| + expected_checksums = checksum_section do |c| c.repo_gem gem_repo2, "rack", "1.0.0" c.repo_gem gem_repo2, "rack-obama", "1.0" end @@ -1239,7 +1239,7 @@ RSpec.describe "the lockfile format" do gem "platform_specific" G - expected_checksums = construct_checksum_section do |c| + expected_checksums = checksum_section do |c| c.repo_gem gem_repo2, "platform_specific", "1.0", "universal-java-16" end diff --git a/spec/bundler/realworld/edgecases_spec.rb b/spec/bundler/realworld/edgecases_spec.rb index d04da0c334..6c523556fb 100644 --- a/spec/bundler/realworld/edgecases_spec.rb +++ b/spec/bundler/realworld/edgecases_spec.rb @@ -8,9 +8,10 @@ RSpec.describe "real world edgecases", :realworld => true do require "bundler/source/rubygems/remote" require "bundler/fetcher" rubygem = Bundler.ui.silence do - source = Bundler::Source::Rubygems::Remote.new(Bundler::URI("https://rubygems.org")) - fetcher = Bundler::Fetcher.new(source) - index = fetcher.specs([#{name.dump}], nil) + remote = Bundler::Source::Rubygems::Remote.new(Bundler::URI("https://rubygems.org")) + source = Bundler::Source::Rubygems.new + fetcher = Bundler::Fetcher.new(remote) + index = fetcher.specs([#{name.dump}], source) requirement = Gem::Requirement.create(#{requirement.dump}) index.search(#{name.dump}).select {|spec| requirement.satisfied_by?(spec.version) }.last end diff --git a/spec/bundler/support/checksums.rb b/spec/bundler/support/checksums.rb index ba7770fda8..7f5ecc14dd 100644 --- a/spec/bundler/support/checksums.rb +++ b/spec/bundler/support/checksums.rb @@ -3,49 +3,80 @@ module Spec module Checksums class ChecksumsBuilder - def initialize - @checksums = [] + def initialize(&block) + @checksums = {} + yield self if block_given? end - def repo_gem(gem_repo, gem_name, gem_version, platform = nil, empty: false) - gem_file = if platform - "#{gem_repo}/gems/#{gem_name}-#{gem_version}-#{platform}.gem" - else - "#{gem_repo}/gems/#{gem_name}-#{gem_version}.gem" + def repo_gem(repo, name, version, platform = Gem::Platform::RUBY) + gem_file = File.join(repo, "gems", "#{Bundler::GemHelpers.spec_full_name(name, version, platform)}.gem") + File.open(gem_file, "rb") do |f| + checksums = Bundler::Checksum.from_io(f, "ChecksumsBuilder") + checksum_entry(checksums, name, version, platform) end + end - checksum = { "sha256" => sha256_checksum(gem_file) } unless empty - @checksums << Bundler::Checksum.new(gem_name, gem_version, platform, checksum) + def no_checksum(name, version, platform = Gem::Platform::RUBY) + checksum_entry(nil, name, version, platform) end - def to_lock - @checksums.map(&:to_lock).sort.join.strip + def checksum_entry(checksums, name, version, platform = Gem::Platform::RUBY) + lock_name = Bundler::GemHelpers.lock_name(name, version, platform) + @checksums[lock_name] = checksums end - private + def to_lock + @checksums.map do |lock_name, checksums| + checksums &&= " #{checksums.map(&:to_lock).join(",")}" + " #{lock_name}#{checksums}\n" + end.sort.join.strip + end + end - def sha256_checksum(file) - File.open(file) do |f| - digest = Bundler::SharedHelpers.digest(:SHA256).new - digest << f.read(16_384) until f.eof? + def checksum_section(&block) + ChecksumsBuilder.new(&block).to_lock + end - digest.hexdigest! - end + def checksum_for_repo_gem(*args) + checksum_section do |c| + c.repo_gem(*args) end end - def construct_checksum_section - checksums = ChecksumsBuilder.new + def gem_no_checksum(*args) + checksum_section do |c| + c.no_checksum(*args) + end + end - yield checksums + # if prefixes is given, removes all checksums where the line + # has any of the prefixes on the line before the checksum + # otherwise, removes all checksums from the lockfile + def remove_checksums_from_lockfile(lockfile, *prefixes) + head, remaining = lockfile.split(/^CHECKSUMS$/, 2) + checksums, tail = remaining.split("\n\n", 2) - checksums.to_lock - end + prefixes = + if prefixes.empty? + nil + else + /(#{prefixes.map {|p| Regexp.escape(p) }.join("|")})/ + end - def checksum_for_repo_gem(*args, **kwargs) - construct_checksum_section do |c| - c.repo_gem(*args, **kwargs) + checksums = checksums.each_line.map do |line| + if prefixes.nil? || line.match?(prefixes) + line.gsub(/ sha256-[a-f0-9]{64}/i, "") + else + line + end end + + head.concat( + "CHECKSUMS", + checksums.join, + "\n\n", + tail + ) end end end |