From 35984510e0a3c192e66571b5bd1ce80f281ad0e8 Mon Sep 17 00:00:00 2001 From: Lars Kanis Date: Sun, 25 Feb 2018 21:33:33 +0100 Subject: [PATCH] Fix path checks for case insensitive filesystem On Windows paths are case insensitive. That means that path comparisons must be done case insensitive. Different lower / upper case characters can happen, when RbConfig::TOPDIR or GEM_HOME are set to a path of different case. This bug was introduced in commit 666ef793c . It stood out in this nokogiri issue: https://github.com/sparklemotion/nokogiri/issues/1726 --- lib/rubygems/package.rb | 10 +++++++++- test/rubygems/test_gem_package.rb | 15 +++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/lib/rubygems/package.rb b/lib/rubygems/package.rb index b924122827..c6368d69a8 100644 --- a/lib/rubygems/package.rb +++ b/lib/rubygems/package.rb @@ -429,6 +429,14 @@ def install_location filename, destination_dir # :nodoc: destination end + def normalize_path(pathname) + if Gem.win_platform? + pathname.downcase + else + pathname + end + end + def mkdir_p_safe mkdir, mkdir_options, destination_dir, file_name destination_dir = realpath File.expand_path(destination_dir) parts = mkdir.split(File::SEPARATOR) @@ -437,7 +445,7 @@ def mkdir_p_safe mkdir, mkdir_options, destination_dir, file_name path = File.expand_path(path + File::SEPARATOR + basename) lstat = File.lstat path rescue nil if !lstat || !lstat.directory? - unless path.start_with? destination_dir and (FileUtils.mkdir path, mkdir_options rescue false) + unless normalize_path(path).start_with? normalize_path(destination_dir) and (FileUtils.mkdir path, mkdir_options rescue false) raise Gem::Package::PathError.new(file_name, destination_dir) end end diff --git a/test/rubygems/test_gem_package.rb b/test/rubygems/test_gem_package.rb index d1664cf285..b9169b16c9 100644 --- a/test/rubygems/test_gem_package.rb +++ b/test/rubygems/test_gem_package.rb @@ -524,6 +524,21 @@ def test_extract_tar_gz_dot_file assert_path_exists extracted end + if Gem.win_platform? + def test_extract_tar_gz_case_insensitive + package = Gem::Package.new @gem + + tgz_io = util_tar_gz do |tar| + tar.add_file 'foo/file.rb', 0644 do |io| io.write 'hi' end + end + + package.extract_tar_gz tgz_io, @destination.upcase + + extracted = File.join @destination, 'foo/file.rb' + assert_path_exists extracted + end + end + def test_install_location package = Gem::Package.new @gem