diff options
author | David RodrÃguez <deivid.rodriguez@riseup.net> | 2022-08-02 10:27:42 +0200 |
---|---|---|
committer | git <svn-admin@ruby-lang.org> | 2022-08-04 13:36:45 +0900 |
commit | 542040fb8375ffd74096ae0615a33bbc90524cb3 (patch) | |
tree | 2cea6b5f9c8275e766f95f9a2137fe78e4ee09cc | |
parent | 0591780a74f9893038d5d794a958621189953e8a (diff) | |
download | ruby-542040fb8375ffd74096ae0615a33bbc90524cb3.tar.gz |
[rubygems/rubygems] Warn dangling symlinks
https://github.com/rubygems/rubygems/commit/425b78637f
-rw-r--r-- | lib/rubygems/installer.rb | 10 | ||||
-rw-r--r-- | lib/rubygems/package.rb | 14 | ||||
-rw-r--r-- | test/rubygems/test_gem_installer.rb | 5 | ||||
-rw-r--r-- | test/rubygems/test_gem_package.rb | 22 |
4 files changed, 39 insertions, 12 deletions
diff --git a/lib/rubygems/installer.rb b/lib/rubygems/installer.rb index 8ec75d1ff7..b764f21a4f 100644 --- a/lib/rubygems/installer.rb +++ b/lib/rubygems/installer.rb @@ -490,15 +490,7 @@ class Gem::Installer spec.executables.each do |filename| filename.tap(&Gem::UNTAINT) bin_path = File.join gem_dir, spec.bindir, filename - - unless File.exist? bin_path - if File.symlink? bin_path - alert_warning "`#{bin_path}` is dangling symlink pointing to `#{File.readlink bin_path}`" - else - alert_warning "`#{bin_path}` does not exist, maybe `gem pristine #{spec.name}` will fix it?" - end - next - end + next unless File.exist? bin_path mode = File.stat(bin_path).mode dir_mode = options[:prog_mode] || (mode | 0111) diff --git a/lib/rubygems/package.rb b/lib/rubygems/package.rb index 8d7aa01f6e..77f9f282d8 100644 --- a/lib/rubygems/package.rb +++ b/lib/rubygems/package.rb @@ -409,6 +409,8 @@ EOM def extract_tar_gz(io, destination_dir, pattern = "*") # :nodoc: directories = [] + symlinks = [] + open_tar_gz io do |tar| tar.each do |entry| full_name = entry.full_name @@ -422,6 +424,8 @@ EOM raise Gem::Package::SymlinkError.new(full_name, real_destination, destination_dir) unless normalize_path(real_destination).start_with? normalize_path(destination_dir + "/") + + symlinks << [full_name, link_target, destination, real_destination] end FileUtils.rm_rf destination @@ -445,12 +449,18 @@ EOM FileUtils.chmod file_mode(entry.header.mode), destination end if entry.file? - File.symlink(entry.header.linkname, destination) if entry.symlink? - verbose destination end end + symlinks.each do |name, target, destination, real_destination| + if File.exist?(real_destination) + File.symlink(target, destination) + else + alert_warning "#{@spec.full_name} ships with a dangling symlink named #{name} pointing to missing #{target} file. Ignoring" + end + end + if dir_mode File.chmod(dir_mode, *directories) end diff --git a/test/rubygems/test_gem_installer.rb b/test/rubygems/test_gem_installer.rb index d269644ade..55f0a074b8 100644 --- a/test/rubygems/test_gem_installer.rb +++ b/test/rubygems/test_gem_installer.rb @@ -756,7 +756,10 @@ gem 'other', version end end - assert_match %r{bin/ascii_binder` is dangling symlink pointing to `bin/asciibinder`}, @ui.error + errors = @ui.error.split("\n") + assert_equal "WARNING: ascii_binder-0.1.10.1 ships with a dangling symlink named bin/ascii_binder pointing to missing bin/asciibinder file. Ignoring", errors.shift + assert_empty errors + assert_empty @ui.output end diff --git a/test/rubygems/test_gem_package.rb b/test/rubygems/test_gem_package.rb index 9e18dacba1..9295f42dba 100644 --- a/test/rubygems/test_gem_package.rb +++ b/test/rubygems/test_gem_package.rb @@ -529,6 +529,7 @@ class TestGemPackage < Gem::Package::TarTestCase def test_extract_tar_gz_symlink_relative_path package = Gem::Package.new @gem + package.verify tgz_io = util_tar_gz do |tar| tar.add_file "relative.rb", 0644 do |io| @@ -557,6 +558,27 @@ class TestGemPackage < Gem::Package::TarTestCase File.read(extracted) end + def test_extract_tar_gz_symlink_broken_relative_path + package = Gem::Package.new @gem + package.verify + + tgz_io = util_tar_gz do |tar| + tar.mkdir "lib", 0755 + tar.add_symlink "lib/foo.rb", "../broken.rb", 0644 + end + + ui = Gem::MockGemUi.new + + use_ui ui do + package.extract_tar_gz tgz_io, @destination + end + + assert_equal "WARNING: a-2 ships with a dangling symlink named lib/foo.rb pointing to missing ../broken.rb file. Ignoring\n", ui.error + + extracted = File.join @destination, "lib/foo.rb" + assert_path_not_exist extracted + end + def test_extract_symlink_parent package = Gem::Package.new @gem |