Skip to content

Commit

Permalink
Don't allow gems to place files outside the installation directory. F…
Browse files Browse the repository at this point in the history
…ixes bug 7751 by Gavin Sinclair.

git-svn-id: http://rubygems.rubyforge.org/svn/trunk@1195 3d4018f9-ac1a-0410-99e9-8a154d859a19
  • Loading branch information
drbrain committed Jan 12, 2007
1 parent 02d2436 commit e890100
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 8 deletions.
6 changes: 6 additions & 0 deletions ChangeLog
@@ -1,3 +1,9 @@
2007-01-12 Eric Hodel <drbrain@segment7.net>

* lib/rubygems/installer.rb (Gem::Installer#extract_files): Don't
allow gems to place files outside the installation directory. Fixes
bug 7751 by Gavin Sinclair.

2007-01-08 Jim Weirich <jim@weirichhouse.org>

* lib/rubygems/specification.rb
Expand Down
22 changes: 14 additions & 8 deletions lib/rubygems/installer.rb
Expand Up @@ -348,14 +348,20 @@ def build_extensions(directory, spec)
#
def extract_files(directory, format)
require 'fileutils'
wd = Dir.getwd
Dir.chdir directory do
format.file_entries.each do |entry, file_data|
path = entry['path'].untaint
FileUtils.mkdir_p File.dirname(path)
File.open(path, "wb") do |out|
out.write file_data
end
format.file_entries.each do |entry, file_data|
path = entry['path'].untaint
if path =~ /\A\// then # for extra sanity
raise Gem::InstallError,
"attempt to install file into #{entry['path'].inspect}"
end
path = File.expand_path File.join(directory, path)
if path !~ /\A#{Regexp.escape directory}/ then
raise Gem::InstallError,
"attempt to install file into #{entry['path'].inspect}"
end
FileUtils.mkdir_p File.dirname(path)
File.open(path, "wb") do |out|
out.write file_data
end
end
end
Expand Down
41 changes: 41 additions & 0 deletions test/test_installer.rb
Expand Up @@ -87,6 +87,47 @@ def test_build_extensions_unsupported
assert_equal '', ui.error
end

def test_extract_files
format = Object.new
def format.file_entries
[[{'size' => 7, 'mode' => 0400, 'path' => 'thefile'}, 'thefile']]
end

@installer.extract_files @tempdir, format

assert_equal 'thefile', File.read(File.join(@tempdir, 'thefile'))
end

def test_extract_files_relative
format = Object.new
def format.file_entries
[[{'size' => 10, 'mode' => 0644, 'path' => '../thefile'}, '../thefile']]
end

e = assert_raise Gem::InstallError do
@installer.extract_files @tempdir, format
end

assert_equal 'attempt to install file into "../thefile"', e.message
assert_equal false, File.file?(File.join(@tempdir, '../thefile')),
"You may need to remove this file if you broke the test once"
end

def test_extract_files_absolute
format = Object.new
def format.file_entries
[[{'size' => 8, 'mode' => 0644, 'path' => '/thefile'}, '/thefile']]
end

e = assert_raise Gem::InstallError do
@installer.extract_files @tempdir, format
end

assert_equal 'attempt to install file into "/thefile"', e.message
assert_equal false, File.file?(File.join('/thefile')),
"You may need to remove this file if you broke the test once"
end

def test_generate_bin_scripts
@installer.options[:wrappers] = true
util_make_exec
Expand Down

0 comments on commit e890100

Please sign in to comment.