Skip to content
This repository was archived by the owner on Apr 14, 2021. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 30 additions & 11 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ else
File.expand_path("tmp/rubygems")
end

def bundler_spec
@bundler_spec ||= Gem::Specification.load("bundler.gemspec")
def development_dependencies
@development_dependencies ||= Gem::Specification.load("bundler.gemspec").development_dependencies
end

# Benchmark task execution
Expand Down Expand Up @@ -43,7 +43,7 @@ namespace :spec do

desc "Ensure spec dependencies are installed"
task :deps do
deps = Hash[bundler_spec.development_dependencies.map do |d|
deps = Hash[development_dependencies.map do |d|
[d.name, d.requirement.to_s]
end]

Expand Down Expand Up @@ -228,7 +228,7 @@ task :rubocop do
end

namespace :man do
ronn_dep = bundler_spec.development_dependencies.find do |dep|
ronn_dep = development_dependencies.find do |dep|
dep.name == "ronn"
end

Expand Down Expand Up @@ -297,30 +297,56 @@ namespace :man do
end
end

automatiek_dep = development_dependencies.find do |dep|
dep.name == "automatiek"
end

automatiek_requirement = automatiek_dep.requirement.to_s

begin
gem "automatiek", automatiek_requirement

require "automatiek"
rescue LoadError
namespace :vendor do
desc "Vendor a specific version of molinillo"
task(:molinillo) { abort "We couldn't activate automatiek (#{automatiek_requirement}). Try `gem install automatiek:'#{automatiek_requirement}'` to be able to vendor gems" }

desc "Vendor a specific version of fileutils"
task(:fileutils) { abort "We couldn't activate automatiek (#{automatiek_requirement}). Try `gem install automatiek:'#{automatiek_requirement}'` to be able to vendor gems" }

desc "Vendor a specific version of thor"
task(:thor) { abort "We couldn't activate automatiek (#{automatiek_requirement}). Try `gem install automatiek:'#{automatiek_requirement}'` to be able to vendor gems" }

desc "Vendor a specific version of net-http-persistent"
task(:"net-http-persistent") { abort "We couldn't activate automatiek (#{automatiek_requirement}). Try `gem install automatiek:'#{automatiek_requirement}'` to be able to vendor gems" }
end
else
desc "Vendor a specific version of molinillo"
Automatiek::RakeTask.new("molinillo") do |lib|
lib.download = { :github => "https://github.com/CocoaPods/Molinillo" }
lib.namespace = "Molinillo"
lib.prefix = "Bundler"
lib.vendor_lib = "lib/bundler/vendor/molinillo"
end

desc "Vendor a specific version of thor"
Automatiek::RakeTask.new("thor") do |lib|
lib.download = { :github => "https://github.com/erikhuda/thor" }
lib.namespace = "Thor"
lib.prefix = "Bundler"
lib.vendor_lib = "lib/bundler/vendor/thor"
end

desc "Vendor a specific version of fileutils"
Automatiek::RakeTask.new("fileutils") do |lib|
lib.download = { :github => "https://github.com/ruby/fileutils" }
lib.namespace = "FileUtils"
lib.prefix = "Bundler"
lib.vendor_lib = "lib/bundler/vendor/fileutils"
end

desc "Vendor a specific version of net-http-persistent"
Automatiek::RakeTask.new("net-http-persistent") do |lib|
lib.download = { :github => "https://github.com/drbrain/net-http-persistent" }
lib.namespace = "Net::HTTP::Persistent"
Expand All @@ -337,13 +363,6 @@ begin
end
lib.send(:extend, mixin)
end
rescue LoadError
namespace :vendor do
task(:fileutils) { abort "Install the automatiek gem to be able to vendor gems." }
task(:molinillo) { abort "Install the automatiek gem to be able to vendor gems." }
task(:thor) { abort "Install the automatiek gem to be able to vendor gems." }
task("net-http-persistent") { abort "Install the automatiek gem to be able to vendor gems." }
end
end

task :override_version do
Expand Down
149 changes: 123 additions & 26 deletions lib/bundler/vendor/fileutils/lib/fileutils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,12 @@
# <tt>:verbose</tt> flags to methods in Bundler::FileUtils.
#

require 'rbconfig'

module Bundler::FileUtils

VERSION = "1.1.0"

def self.private_module_function(name) #:nodoc:
module_function name
private_class_method name
Expand Down Expand Up @@ -117,8 +121,9 @@ def pwd
#
def cd(dir, verbose: nil, &block) # :yield: dir
fu_output_message "cd #{dir}" if verbose
Dir.chdir(dir, &block)
result = Dir.chdir(dir, &block)
fu_output_message 'cd -' if verbose and block
result
end
module_function :cd

Expand Down Expand Up @@ -245,15 +250,15 @@ def rmdir(list, parents: nil, noop: nil, verbose: nil)
fu_output_message "rmdir #{parents ? '-p ' : ''}#{list.join ' '}" if verbose
return if noop
list.each do |dir|
begin
Dir.rmdir(dir = remove_trailing_slash(dir))
if parents
Dir.rmdir(dir = remove_trailing_slash(dir))
if parents
begin
until (parent = File.dirname(dir)) == '.' or parent == dir
dir = parent
Dir.rmdir(dir)
end
rescue Errno::ENOTEMPTY, Errno::EEXIST, Errno::ENOENT
end
rescue Errno::ENOTEMPTY, Errno::EEXIST, Errno::ENOENT
end
end
end
Expand Down Expand Up @@ -293,6 +298,39 @@ def ln(src, dest, force: nil, noop: nil, verbose: nil)
alias link ln
module_function :link

#
# :call-seq:
# Bundler::FileUtils.cp_lr(src, dest, noop: nil, verbose: nil, dereference_root: true, remove_destination: false)
#
# Hard link +src+ to +dest+. If +src+ is a directory, this method links
# all its contents recursively. If +dest+ is a directory, links
# +src+ to +dest/src+.
#
# +src+ can be a list of files.
#
# # Installing the library "mylib" under the site_ruby directory.
# Bundler::FileUtils.rm_r site_ruby + '/mylib', :force => true
# Bundler::FileUtils.cp_lr 'lib/', site_ruby + '/mylib'
#
# # Examples of linking several files to target directory.
# Bundler::FileUtils.cp_lr %w(mail.rb field.rb debug/), site_ruby + '/tmail'
# Bundler::FileUtils.cp_lr Dir.glob('*.rb'), '/home/aamine/lib/ruby', :noop => true, :verbose => true
#
# # If you want to link all contents of a directory instead of the
# # directory itself, c.f. src/x -> dest/x, src/y -> dest/y,
# # use the following code.
# Bundler::FileUtils.cp_lr 'src/.', 'dest' # cp_lr('src', 'dest') makes dest/src, but this doesn't.
#
def cp_lr(src, dest, noop: nil, verbose: nil,
dereference_root: true, remove_destination: false)
fu_output_message "cp -lr#{remove_destination ? ' --remove-destination' : ''} #{[src,dest].flatten.join ' '}" if verbose
return if noop
fu_each_src_dest(src, dest) do |s, d|
link_entry s, d, dereference_root, remove_destination
end
end
module_function :cp_lr

#
# :call-seq:
# Bundler::FileUtils.ln_s(target, link, force: nil, noop: nil, verbose: nil)
Expand Down Expand Up @@ -339,6 +377,26 @@ def ln_sf(src, dest, noop: nil, verbose: nil)
end
module_function :ln_sf

#
# Hard links a file system entry +src+ to +dest+.
# If +src+ is a directory, this method links its contents recursively.
#
# Both of +src+ and +dest+ must be a path name.
# +src+ must exist, +dest+ must not exist.
#
# If +dereference_root+ is true, this method dereferences the tree root.
#
# If +remove_destination+ is true, this method removes each destination file before copy.
#
def link_entry(src, dest, dereference_root = false, remove_destination = false)
Entry_.new(src, nil, dereference_root).traverse do |ent|
destent = Entry_.new(dest, ent.rel, false)
File.unlink destent.path if remove_destination && File.file?(destent.path)
ent.link destent.path
end
end
module_function :link_entry

#
# Copies a file content +src+ to +dest+. If +dest+ is a directory,
# copies +src+ to +dest/src+.
Expand Down Expand Up @@ -412,7 +470,7 @@ def cp_r(src, dest, preserve: nil, noop: nil, verbose: nil,
def copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false)
Entry_.new(src, nil, dereference_root).wrap_traverse(proc do |ent|
destent = Entry_.new(dest, ent.rel, false)
File.unlink destent.path if remove_destination && File.file?(destent.path)
File.unlink destent.path if remove_destination && (File.file?(destent.path) || File.symlink?(destent.path))
ent.copy destent.path
end, proc do |ent|
destent = Entry_.new(dest, ent.rel, false)
Expand Down Expand Up @@ -486,7 +544,7 @@ def mv(src, dest, force: nil, noop: nil, verbose: nil, secure: nil)
module_function :move

def rename_cannot_overwrite_file? #:nodoc:
/emx/ =~ RUBY_PLATFORM
/emx/ =~ RbConfig::CONFIG['host_os']
end
private_module_function :rename_cannot_overwrite_file?

Expand Down Expand Up @@ -601,8 +659,8 @@ def rm_rf(list, noop: nil, verbose: nil, secure: nil)
#
# For details of this security vulnerability, see Perl's case:
#
# * http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2005-0448
# * http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2004-0452
# * https://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2005-0448
# * https://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2004-0452
#
# For fileutils.rb, this vulnerability is reported in [ruby-dev:26100].
#
Expand All @@ -626,22 +684,38 @@ def remove_entry_secure(path, force = false)
unless parent_st.sticky?
raise ArgumentError, "parent directory is world writable, Bundler::FileUtils#remove_entry_secure does not work; abort: #{path.inspect} (parent directory mode #{'%o' % parent_st.mode})"
end

# freeze tree root
euid = Process.euid
File.open(fullpath + '/.') {|f|
unless fu_stat_identical_entry?(st, f.stat)
# symlink (TOC-to-TOU attack?)
File.unlink fullpath
return
end
f.chown euid, -1
f.chmod 0700
unless fu_stat_identical_entry?(st, File.lstat(fullpath))
# TOC-to-TOU attack?
File.unlink fullpath
return
end
}
dot_file = fullpath + "/."
begin
File.open(dot_file) {|f|
unless fu_stat_identical_entry?(st, f.stat)
# symlink (TOC-to-TOU attack?)
File.unlink fullpath
return
end
f.chown euid, -1
f.chmod 0700
}
rescue EISDIR # JRuby in non-native mode can't open files as dirs
File.lstat(dot_file).tap {|fstat|
unless fu_stat_identical_entry?(st, fstat)
# symlink (TOC-to-TOU attack?)
File.unlink fullpath
return
end
File.chown euid, -1, dot_file
File.chmod 0700, dot_file
}
end

unless fu_stat_identical_entry?(st, File.lstat(fullpath))
# TOC-to-TOU attack?
File.unlink fullpath
return
end

# ---- tree root is frozen ----
root = Entry_.new(path)
root.preorder_traverse do |ent|
Expand Down Expand Up @@ -742,8 +816,15 @@ def compare_file(a, b)
#
def compare_stream(a, b)
bsize = fu_stream_blksize(a, b)
sa = String.new(capacity: bsize)
sb = String.new(capacity: bsize)

if RUBY_VERSION > "2.4"
sa = String.new(capacity: bsize)
sb = String.new(capacity: bsize)
else
sa = String.new
sb = String.new
end

begin
a.read(bsize, sa)
b.read(bsize, sb)
Expand Down Expand Up @@ -1068,7 +1149,7 @@ module StreamUtils_
private

def fu_windows?
/mswin|mingw|bccwin|emx/ =~ RUBY_PLATFORM
/mswin|mingw|bccwin|emx/ =~ RbConfig::CONFIG['host_os']
end

def fu_copy_stream0(src, dest, blksize = nil) #:nodoc:
Expand Down Expand Up @@ -1250,6 +1331,22 @@ def chown(uid, gid)
end
end

def link(dest)
case
when directory?
if !File.exist?(dest) and descendant_directory?(dest, path)
raise ArgumentError, "cannot link directory %s to itself %s" % [path, dest]
end
begin
Dir.mkdir dest
rescue
raise unless File.directory?(dest)
end
else
File.link path(), dest
end
end

def copy(dest)
lstat
case
Expand Down
18 changes: 14 additions & 4 deletions lib/bundler/vendor/thor/lib/thor/actions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,10 @@ def destination_root=(root)
# the script started).
#
def relative_to_original_destination_root(path, remove_dot = true)
path = path.dup
if path.gsub!(@destination_stack[0], ".")
root = @destination_stack[0]
if path.start_with?(root) && [File::SEPARATOR, File::ALT_SEPARATOR, nil, ''].include?(path[root.size..root.size])
path = path.dup
path[0...root.size] = '.'
remove_dot ? (path[2..-1] || "") : path
else
path
Expand Down Expand Up @@ -217,6 +219,7 @@ def apply(path, config = {})
shell.padding += 1 if verbose

contents = if is_uri
require "open-uri"
open(path, "Accept" => "application/x-thor-template", &:read)
else
open(path, &:read)
Expand Down Expand Up @@ -252,9 +255,16 @@ def run(command, config = {})

say_status :run, desc, config.fetch(:verbose, true)

unless options[:pretend]
config[:capture] ? `#{command}` : system(command.to_s)
return if options[:pretend]

result = config[:capture] ? `#{command}` : system(command.to_s)

if config[:abort_on_failure]
success = config[:capture] ? $?.success? : result
abort unless success
end

result
end

# Executes a ruby script (taking into account WIN32 platform quirks).
Expand Down
Loading