|
|
121925 |
diff --git a/lib/rubygems/package.rb b/lib/rubygems/package.rb
|
|
|
121925 |
index 13eb25bd26..9b1cb3a142 100644
|
|
|
121925 |
--- a/lib/rubygems/package.rb
|
|
|
121925 |
+++ b/lib/rubygems/package.rb
|
|
|
121925 |
@@ -332,7 +332,16 @@ EOM
|
|
|
121925 |
|
|
|
121925 |
FileUtils.rm_rf destination
|
|
|
121925 |
|
|
|
121925 |
- FileUtils.mkdir_p File.dirname destination
|
|
|
121925 |
+ mkdir_options = {}
|
|
|
121925 |
+ mkdir_options[:mode] = entry.header.mode if entry.directory?
|
|
|
121925 |
+ mkdir =
|
|
|
121925 |
+ if entry.directory? then
|
|
|
121925 |
+ destination
|
|
|
121925 |
+ else
|
|
|
121925 |
+ File.dirname destination
|
|
|
121925 |
+ end
|
|
|
121925 |
+
|
|
|
121925 |
+ mkdir_p_safe mkdir, mkdir_options, destination_dir, entry.full_name
|
|
|
121925 |
|
|
|
121925 |
open destination, 'wb', entry.header.mode do |out|
|
|
|
121925 |
out.write entry.read
|
|
|
121925 |
@@ -367,12 +376,9 @@ EOM
|
|
|
121925 |
raise Gem::Package::PathError.new(filename, destination_dir) if
|
|
|
121925 |
filename.start_with? '/'
|
|
|
121925 |
|
|
|
121925 |
- destination_dir = File.realpath destination_dir if
|
|
|
121925 |
- File.respond_to? :realpath
|
|
|
121925 |
+ destination_dir = realpath destination_dir
|
|
|
121925 |
|
|
|
121925 |
destination = File.join destination_dir, filename
|
|
|
121925 |
- destination = File.realpath destination if
|
|
|
121925 |
- File.respond_to? :realpath
|
|
|
121925 |
destination = File.expand_path destination
|
|
|
121925 |
|
|
|
121925 |
raise Gem::Package::PathError.new(destination, destination_dir) unless
|
|
|
121925 |
@@ -382,6 +388,22 @@ EOM
|
|
|
121925 |
destination
|
|
|
121925 |
end
|
|
|
121925 |
|
|
|
121925 |
+ def mkdir_p_safe mkdir, mkdir_options, destination_dir, file_name
|
|
|
121925 |
+ destination_dir = realpath File.expand_path(destination_dir)
|
|
|
121925 |
+ parts = mkdir.split(File::SEPARATOR)
|
|
|
121925 |
+ parts.reduce do |path, basename|
|
|
|
121925 |
+ path = realpath path unless path == ""
|
|
|
121925 |
+ path = File.expand_path(path + File::SEPARATOR + basename)
|
|
|
121925 |
+ lstat = File.lstat path rescue nil
|
|
|
121925 |
+ if !lstat || !lstat.directory?
|
|
|
121925 |
+ unless path.start_with? destination_dir and (FileUtils.mkdir path, mkdir_options rescue false)
|
|
|
121925 |
+ raise Gem::Package::PathError.new(file_name, destination_dir)
|
|
|
121925 |
+ end
|
|
|
121925 |
+ end
|
|
|
121925 |
+ path
|
|
|
121925 |
+ end
|
|
|
121925 |
+ end
|
|
|
121925 |
+
|
|
|
121925 |
##
|
|
|
121925 |
# Loads a Gem::Specification from the TarEntry +entry+
|
|
|
121925 |
|
|
|
121925 |
@@ -560,6 +582,16 @@ EOM
|
|
|
121925 |
raise Gem::Package::FormatError.new(e.message, entry.full_name)
|
|
|
121925 |
end
|
|
|
121925 |
|
|
|
121925 |
+ if File.respond_to? :realpath
|
|
|
121925 |
+ def realpath file
|
|
|
121925 |
+ File.realpath file
|
|
|
121925 |
+ end
|
|
|
121925 |
+ else
|
|
|
121925 |
+ def realpath file
|
|
|
121925 |
+ file
|
|
|
121925 |
+ end
|
|
|
121925 |
+ end
|
|
|
121925 |
+
|
|
|
121925 |
end
|
|
|
121925 |
|
|
|
121925 |
require 'rubygems/package/digest_io'
|
|
|
121925 |
--
|
|
|
121925 |
2.20.1
|
|
|
121925 |
|