diff options
| author | Martin Emde <martin.emde@gmail.com> | 2023-12-17 13:22:38 -0800 |
|---|---|---|
| committer | Hiroshi SHIBATA <hsbt@ruby-lang.org> | 2024-01-24 13:50:16 +0900 |
| commit | 01f9766aa05182a7bbdc914a5dcd8a36ebade861 (patch) | |
| tree | a93628420b1a39603f4be3bb31b83a45feb09d22 | |
| parent | 2defa9f4ae52c99e64a02b7f78362fbd788a1fd0 (diff) | |
Ensure File.open applies default umask on gem extract
| -rw-r--r-- | lib/rubygems/package.rb | 8 | ||||
| -rw-r--r-- | test/rubygems/test_gem.rb | 8 | ||||
| -rw-r--r-- | test/rubygems/test_gem_package.rb | 37 |
3 files changed, 47 insertions, 6 deletions
diff --git a/lib/rubygems/package.rb b/lib/rubygems/package.rb index 387e40ffd7..7b4cab7964 100644 --- a/lib/rubygems/package.rb +++ b/lib/rubygems/package.rb @@ -448,13 +448,15 @@ EOM end unless directories.include?(mkdir) - FileUtils.mkdir_p mkdir, mode: dir_mode ? 0o755 : (entry.header.mode if entry.directory?) + mkdir_mode = 0o755 if dir_mode + mkdir_mode ||= entry.header.mode if entry.directory? + mkdir_mode &= ~File.umask if mkdir_mode + FileUtils.mkdir_p mkdir, mode: mkdir_mode directories << mkdir end if entry.file? - File.open(destination, "wb") {|out| copy_stream(entry, out) } - FileUtils.chmod file_mode(entry.header.mode), destination + File.open(destination, "wb", file_mode(entry.header.mode)) {|out| copy_stream(entry, out) } end verbose destination diff --git a/test/rubygems/test_gem.rb b/test/rubygems/test_gem.rb index d4c307978e..8dc8563aaf 100644 --- a/test/rubygems/test_gem.rb +++ b/test/rubygems/test_gem.rb @@ -161,13 +161,17 @@ class TestGem < Gem::TestCase format_executable: format_executable, } Dir.chdir @tempdir do + # use chmod to set global permissions (so umask doesn't bypass our choice) to ensure they are masked on install Dir.mkdir "bin" + File.chmod 0o777, "bin" Dir.mkdir "data" + File.chmod 0o777, "data" File.write "bin/foo", "#!/usr/bin/env ruby\n" - File.chmod 0o755, "bin/foo" + File.chmod 0o777, "bin/foo" File.write "data/foo.txt", "blah\n" + File.chmod 0o666, "data/foo.txt" spec_fetcher do |f| f.gem "foo", 1 do |s| @@ -180,7 +184,7 @@ class TestGem < Gem::TestCase prog_mode = (options[:prog_mode] & mask).to_s(8) dir_mode = (options[:dir_mode] & mask).to_s(8) - data_mode = (options[:data_mode] & mask).to_s(8) + data_mode = (options[:data_mode] & mask & (~File.umask)).to_s(8) prog_name = "foo" prog_name = RbConfig::CONFIG["ruby_install_name"].sub("ruby", "foo") if options[:format_executable] expected = { diff --git a/test/rubygems/test_gem_package.rb b/test/rubygems/test_gem_package.rb index 2065864107..7adbc695ec 100644 --- a/test/rubygems/test_gem_package.rb +++ b/test/rubygems/test_gem_package.rb @@ -523,7 +523,42 @@ class TestGemPackage < Gem::Package::TarTestCase filepath = File.join @destination, "README.rdoc" assert_path_exist filepath - assert_equal 0o104444, File.stat(filepath).mode + assert_equal 0o100444.to_s(8), File.stat(filepath).mode.to_s(8) + end + + def test_extract_file_umask_global_permissions + pend "chmod not supported" if Gem.win_platform? + + package = Gem::Package.new @gem + + tgz_io = util_tar_gz do |tar| + tar.mkdir "lib", 0o777 + tar.add_file "bin/global", 0o777 do |io| + io.write "#!/bin/ruby\nputs 'hello world'" + end + tar.add_file "lib/global.rb", 0o666 do |io| + io.write "puts 'hello world'" + end + end + + package.extract_tar_gz tgz_io, @destination + + dirpath = File.join @destination, "lib" + assert_path_exist dirpath + mode = 0o40755 & (~File.umask) + assert_equal mode.to_s(8), File.stat(dirpath).mode.to_s(8) + + filepath = File.join @destination, "lib", "global.rb" + assert_path_exist filepath + assert_equal "puts 'hello world'", File.read(filepath) + mode = 0o100644 & (~File.umask) + assert_equal mode.to_s(8), File.stat(filepath).mode.to_s(8) + + filepath = File.join @destination, "bin", "global" + assert_path_exist filepath + assert_equal "#!/bin/ruby\nputs 'hello world'", File.read(filepath) + mode = 0o100755 & (~File.umask) + assert_equal mode.to_s(8), File.stat(filepath).mode.to_s(8) end def test_extract_tar_gz_absolute |
