From 8bb61077ad02c2b57eb5727b7da8a7a4fff28ef3 Mon Sep 17 00:00:00 2001 From: negi0109 Date: Sun, 10 Sep 2023 17:01:15 +0000 Subject: [PATCH] [rubygems/rubygems] Fixed false positive SymlinkError in symbolic link directory https://github.com/rubygems/rubygems/commit/58173ff2ea --- lib/rubygems/package.rb | 4 +++- test/rubygems/test_gem_package.rb | 26 ++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/lib/rubygems/package.rb b/lib/rubygems/package.rb index ba05fadbaf..ee64798cbb 100644 --- a/lib/rubygems/package.rb +++ b/lib/rubygems/package.rb @@ -413,6 +413,8 @@ EOM # extracted. def extract_tar_gz(io, destination_dir, pattern = "*") # :nodoc: + real_destination_dir = File.realpath(destination_dir) + directories = [] symlinks = [] @@ -428,7 +430,7 @@ EOM real_destination = link_target.start_with?("/") ? link_target : File.expand_path(link_target, File.dirname(destination)) raise Gem::Package::SymlinkError.new(full_name, real_destination, destination_dir) unless - normalize_path(real_destination).start_with? normalize_path(destination_dir + "/") + normalize_path(real_destination).start_with? normalize_path(real_destination_dir + "/") symlinks << [full_name, link_target, destination, real_destination] end diff --git a/test/rubygems/test_gem_package.rb b/test/rubygems/test_gem_package.rb index 6161e81f62..68dbf119a4 100644 --- a/test/rubygems/test_gem_package.rb +++ b/test/rubygems/test_gem_package.rb @@ -574,6 +574,32 @@ class TestGemPackage < Gem::Package::TarTestCase File.read(extracted) end + def test_extract_symlink_into_symlink_dir + package = Gem::Package.new @gem + tgz_io = util_tar_gz do |tar| + tar.mkdir "lib", 0o755 + tar.add_symlink "lib/link", "./inside.rb", 0o644 + tar.add_file "lib/inside.rb", 0o644 do |io| + io.write "hi" + end + end + + destination_subdir = File.join @destination, "subdir" + FileUtils.mkdir_p destination_subdir + + destination_linkdir = File.join @destination, "linkdir" + File.symlink(destination_subdir, destination_linkdir) + + package.extract_tar_gz tgz_io, destination_linkdir + + extracted = File.join destination_subdir, "lib/link" + assert_path_exist extracted + assert_equal "./inside.rb", + File.readlink(extracted) + assert_equal "hi", + File.read(extracted) + end + def test_extract_tar_gz_symlink_broken_relative_path package = Gem::Package.new @gem package.verify