Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 425b786

Browse files
Warn dangling symlinks
1 parent 3973773 commit 425b786

File tree

4 files changed

+39
-12
lines changed

4 files changed

+39
-12
lines changed

lib/rubygems/installer.rb

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -490,15 +490,7 @@ def generate_bin # :nodoc:
490490
spec.executables.each do |filename|
491491
filename.tap(&Gem::UNTAINT)
492492
bin_path = File.join gem_dir, spec.bindir, filename
493-
494-
unless File.exist? bin_path
495-
if File.symlink? bin_path
496-
alert_warning "`#{bin_path}` is dangling symlink pointing to `#{File.readlink bin_path}`"
497-
else
498-
alert_warning "`#{bin_path}` does not exist, maybe `gem pristine #{spec.name}` will fix it?"
499-
end
500-
next
501-
end
493+
next unless File.exist? bin_path
502494

503495
mode = File.stat(bin_path).mode
504496
dir_mode = options[:prog_mode] || (mode | 0111)

lib/rubygems/package.rb

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,8 @@ def extract_files(destination_dir, pattern = "*")
409409

410410
def extract_tar_gz(io, destination_dir, pattern = "*") # :nodoc:
411411
directories = []
412+
symlinks = []
413+
412414
open_tar_gz io do |tar|
413415
tar.each do |entry|
414416
full_name = entry.full_name
@@ -422,6 +424,8 @@ def extract_tar_gz(io, destination_dir, pattern = "*") # :nodoc:
422424

423425
raise Gem::Package::SymlinkError.new(full_name, real_destination, destination_dir) unless
424426
normalize_path(real_destination).start_with? normalize_path(destination_dir + "/")
427+
428+
symlinks << [full_name, link_target, destination, real_destination]
425429
end
426430

427431
FileUtils.rm_rf destination
@@ -445,12 +449,18 @@ def extract_tar_gz(io, destination_dir, pattern = "*") # :nodoc:
445449
FileUtils.chmod file_mode(entry.header.mode), destination
446450
end if entry.file?
447451

448-
File.symlink(entry.header.linkname, destination) if entry.symlink?
449-
450452
verbose destination
451453
end
452454
end
453455

456+
symlinks.each do |name, target, destination, real_destination|
457+
if File.exist?(real_destination)
458+
File.symlink(target, destination)
459+
else
460+
alert_warning "#{@spec.full_name} ships with a dangling symlink named #{name} pointing to missing #{target} file. Ignoring"
461+
end
462+
end
463+
454464
if dir_mode
455465
File.chmod(dir_mode, *directories)
456466
end

test/rubygems/test_gem_installer.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -756,7 +756,10 @@ def test_generate_bin_with_dangling_symlink
756756
end
757757
end
758758

759-
assert_match %r{bin/ascii_binder` is dangling symlink pointing to `bin/asciibinder`}, @ui.error
759+
errors = @ui.error.split("\n")
760+
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
761+
assert_empty errors
762+
760763
assert_empty @ui.output
761764
end
762765

test/rubygems/test_gem_package.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,7 @@ def test_extract_tar_gz_absolute
529529

530530
def test_extract_tar_gz_symlink_relative_path
531531
package = Gem::Package.new @gem
532+
package.verify
532533

533534
tgz_io = util_tar_gz do |tar|
534535
tar.add_file "relative.rb", 0644 do |io|
@@ -557,6 +558,27 @@ def test_extract_tar_gz_symlink_relative_path
557558
File.read(extracted)
558559
end
559560

561+
def test_extract_tar_gz_symlink_broken_relative_path
562+
package = Gem::Package.new @gem
563+
package.verify
564+
565+
tgz_io = util_tar_gz do |tar|
566+
tar.mkdir "lib", 0755
567+
tar.add_symlink "lib/foo.rb", "../broken.rb", 0644
568+
end
569+
570+
ui = Gem::MockGemUi.new
571+
572+
use_ui ui do
573+
package.extract_tar_gz tgz_io, @destination
574+
end
575+
576+
assert_equal "WARNING: a-2 ships with a dangling symlink named lib/foo.rb pointing to missing ../broken.rb file. Ignoring\n", ui.error
577+
578+
extracted = File.join @destination, "lib/foo.rb"
579+
assert_path_not_exist extracted
580+
end
581+
560582
def test_extract_symlink_parent
561583
package = Gem::Package.new @gem
562584

0 commit comments

Comments
 (0)