@@ -835,79 +835,100 @@ def test_extract_tar_gz_case_insensitive
835835 end
836836 end
837837
838- def test_install_location
839- package = Gem ::Package . new @gem
840-
841- file = "file.rb" . dup
842-
843- destination = package . install_location file , @destination
844-
845- assert_equal File . join ( @destination , "file.rb" ) , destination
846- end
838+ # The following tests exercise install_location's path resolution and
839+ # traversal protection through the real extraction path (extract_tar_gz)
840+ # rather than calling the private helper directly. The absolute-path case is
841+ # already covered by test_extract_tar_gz_absolute.
847842
848- def test_install_location_absolute
843+ def test_extract_tar_gz_basic_file
849844 package = Gem ::Package . new @gem
850845
851- e = assert_raise Gem ::Package ::PathError do
852- package . install_location "/absolute.rb" , @destination
846+ tgz_io = util_tar_gz do |tar |
847+ tar . add_file "file.rb" , 0o644 do |io |
848+ io . write "hi"
849+ end
853850 end
854851
855- assert_equal ( "installing into parent path /absolute.rb of " \
856- "#{ @destination } is not allowed" , e . message )
852+ package . extract_tar_gz tgz_io , @destination
853+
854+ extracted = File . join @destination , "file.rb"
855+ assert_path_exist extracted
856+ assert_equal "hi" , File . read ( extracted )
857857 end
858858
859- def test_install_location_dots
859+ def test_extract_tar_gz_collapses_parent_dots
860860 package = Gem ::Package . new @gem
861861
862- file = "file.rb"
863-
864- destination = File . join @destination , "foo" , ".." , "bar"
865-
866- FileUtils . mkdir_p File . join @destination , "foo"
867- FileUtils . mkdir_p File . expand_path destination
862+ tgz_io = util_tar_gz do |tar |
863+ tar . add_file "foo/../bar/file.rb" , 0o644 do |io |
864+ io . write "hi"
865+ end
866+ end
868867
869- destination = package . install_location file , destination
868+ package . extract_tar_gz tgz_io , @ destination
870869
871- # this test only fails on ruby missing File.realpath
872- assert_equal File . join ( @destination , "bar" , "file.rb" ) , destination
870+ extracted = File . join @destination , "bar" , "file.rb"
871+ assert_path_exist extracted
872+ assert_equal "hi" , File . read ( extracted )
873+ assert_path_not_exist File . join ( @destination , "foo" )
873874 end
874875
875- def test_install_location_extra_slash
876+ def test_extract_tar_gz_collapses_extra_slash
876877 package = Gem ::Package . new @gem
877878
878- file = "foo//file.rb" . dup
879+ tgz_io = util_tar_gz do |tar |
880+ tar . add_file "foo//file.rb" , 0o644 do |io |
881+ io . write "hi"
882+ end
883+ end
879884
880- destination = package . install_location file , @destination
885+ package . extract_tar_gz tgz_io , @destination
881886
882- assert_equal File . join ( @destination , "foo" , "file.rb" ) , destination
887+ extracted = File . join @destination , "foo" , "file.rb"
888+ assert_path_exist extracted
889+ assert_equal "hi" , File . read ( extracted )
883890 end
884891
885- def test_install_location_relative
892+ def test_extract_tar_gz_rejects_relative_escape
886893 package = Gem ::Package . new @gem
887894
895+ tgz_io = util_tar_gz do |tar |
896+ tar . add_file "../relative.rb" , 0o644 do |io |
897+ io . write "hi"
898+ end
899+ end
900+
888901 e = assert_raise Gem ::Package ::PathError do
889- package . install_location "../relative.rb" , @destination
902+ package . extract_tar_gz tgz_io , @destination
890903 end
891904
892905 parent = File . expand_path File . join @destination , "../relative.rb"
893906
894907 assert_equal ( "installing into parent path #{ parent } of " \
895908 "#{ @destination } is not allowed" , e . message )
909+ assert_path_not_exist parent
896910 end
897911
898- def test_install_location_suffix
912+ def test_extract_tar_gz_rejects_suffix_escape
899913 package = Gem ::Package . new @gem
900914
901915 filename = "../#{ File . basename ( @destination ) } suffix.rb"
902916
917+ tgz_io = util_tar_gz do |tar |
918+ tar . add_file filename , 0o644 do |io |
919+ io . write "hi"
920+ end
921+ end
922+
903923 e = assert_raise Gem ::Package ::PathError do
904- package . install_location filename , @destination
924+ package . extract_tar_gz tgz_io , @destination
905925 end
906926
907927 parent = File . expand_path File . join @destination , filename
908928
909929 assert_equal ( "installing into parent path #{ parent } of " \
910930 "#{ @destination } is not allowed" , e . message )
931+ assert_path_not_exist parent
911932 end
912933
913934 def test_load_spec_from_metadata
0 commit comments