diff options
author | David RodrÃguez <[email protected]> | 2024-08-30 18:57:20 +0200 |
---|---|---|
committer | git <[email protected]> | 2024-09-02 14:01:15 +0000 |
commit | bb511c3f10918efdcc4d5efd980561903e67dc10 (patch) | |
tree | 85f47cbdf70700e3eb191959755a5151392c3448 | |
parent | b00b0d5f8fb9b3e39c55289b67b9320ebaddd5d3 (diff) |
[rubygems/rubygems] Don't try to remove previous install folder if it's empty
Ruby ships with empty directories for default gems. If Ruby
installations has unsafe world-writable permissions, we will complain
when about to install a gem that happens to be also a default gem,
because we'll start by removing the previous install folder and that's
supposed to be insecure due to too loose permissions.
However, if the folder is empty, we don't actually need to remove
anything, so we can skip the whole thing, avoiding the errors.
https://github.com/rubygems/rubygems/commit/2f3cd8ac4e
-rw-r--r-- | lib/bundler/rubygems_gem_installer.rb | 1 | ||||
-rw-r--r-- | spec/bundler/commands/install_spec.rb | 28 |
2 files changed, 29 insertions, 0 deletions
diff --git a/lib/bundler/rubygems_gem_installer.rb b/lib/bundler/rubygems_gem_installer.rb index 3ec73452b3..858ebf32cf 100644 --- a/lib/bundler/rubygems_gem_installer.rb +++ b/lib/bundler/rubygems_gem_installer.rb @@ -150,6 +150,7 @@ module Bundler def strict_rm_rf(dir) return unless File.exist?(dir) + return if Dir.empty?(dir) parent = File.dirname(dir) parent_st = File.stat(parent) diff --git a/spec/bundler/commands/install_spec.rb b/spec/bundler/commands/install_spec.rb index d4bc1d2922..9353d24d95 100644 --- a/spec/bundler/commands/install_spec.rb +++ b/spec/bundler/commands/install_spec.rb @@ -1059,6 +1059,34 @@ RSpec.describe "bundle install with gem sources" do end end + describe "when gems path is world writable (no sticky bit set), but previous install is just an empty dir (like it happens with default gems)", :permissions do + let(:gems_path) { bundled_app("vendor/#{Bundler.ruby_scope}/gems") } + let(:full_path) { gems_path.join("foo-1.0.0") } + + before do + build_repo4 do + build_gem "foo", "1.0.0" do |s| + s.write "CHANGELOG.md", "foo" + end + end + + gemfile <<-G + source "https://gem.repo4" + gem 'foo' + G + end + + it "does not try to remove the directory and thus don't abort with an error about unsafe directory removal" do + bundle "config set --local path vendor" + + FileUtils.mkdir_p(gems_path) + FileUtils.chmod(0o777, gems_path) + Dir.mkdir(full_path) + + bundle "install" + end + end + describe "when bundle cache path does not have write access", :permissions do let(:cache_path) { bundled_app("vendor/#{Bundler.ruby_scope}/cache") } |