mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* lib/fileutils.rb (FileUtils.chmod{,_R}): Enhance the symbolic
mode parser to support the permission symbols u/g/o and multiple actions as defined in SUS, so that chmod("g=o+w", file) works as expected. Invalid symbolic modes are now rejected with ArgumentError. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@41782 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
45116b6a6d
commit
a0011cd54d
3 changed files with 94 additions and 46 deletions
|
@ -1,9 +1,15 @@
|
|||
Fri Jul 5 01:23:33 2013 Akinori MUSHA <knu@iDaemons.org>
|
||||
Fri Jul 5 02:14:00 2013 Akinori MUSHA <knu@iDaemons.org>
|
||||
|
||||
* lib/fileutils.rb (FileUtils#symbolic_modes_to_i): Fix the wrong
|
||||
character class [+-=], which happened to match all desired
|
||||
characters but also match undesired characters.
|
||||
|
||||
* lib/fileutils.rb (FileUtils.chmod{,_R}): Enhance the symbolic
|
||||
mode parser to support the permission symbols u/g/o and multiple
|
||||
actions as defined in SUS, so that chmod("g=o+w", file) works as
|
||||
expected. Invalid symbolic modes are now rejected with
|
||||
ArgumentError.
|
||||
|
||||
Fri Jul 5 00:25:39 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* lib/mkmf.rb (have_framework): allow header file to check.
|
||||
|
|
106
lib/fileutils.rb
106
lib/fileutils.rb
|
@ -868,62 +868,78 @@ module FileUtils
|
|||
OPT_TABLE['install'] = [:mode, :preserve, :noop, :verbose]
|
||||
|
||||
def user_mask(target) #:nodoc:
|
||||
mask = 0
|
||||
target.each_byte do |byte_chr|
|
||||
case byte_chr.chr
|
||||
when "u"
|
||||
mask |= 04700
|
||||
when "g"
|
||||
mask |= 02070
|
||||
when "o"
|
||||
mask |= 01007
|
||||
when "a"
|
||||
mask |= 07777
|
||||
target.each_char.inject(0) do |mask, chr|
|
||||
case chr
|
||||
when "u"
|
||||
mask | 04700
|
||||
when "g"
|
||||
mask | 02070
|
||||
when "o"
|
||||
mask | 01007
|
||||
when "a"
|
||||
mask | 07777
|
||||
else
|
||||
raise ArgumentError, "invalid `who' symbol in file mode: #{chr}"
|
||||
end
|
||||
end
|
||||
mask
|
||||
end
|
||||
private_module_function :user_mask
|
||||
|
||||
def mode_mask(mode, path) #:nodoc:
|
||||
mask = 0
|
||||
mode.each_byte do |byte_chr|
|
||||
case byte_chr.chr
|
||||
when "r"
|
||||
mask |= 0444
|
||||
when "w"
|
||||
mask |= 0222
|
||||
when "x"
|
||||
mask |= 0111
|
||||
when "X"
|
||||
mask |= 0111 if FileTest::directory? path
|
||||
when "s"
|
||||
mask |= 06000
|
||||
when "t"
|
||||
mask |= 01000
|
||||
end
|
||||
def apply_mask(mode, user_mask, op, mode_mask)
|
||||
case op
|
||||
when '='
|
||||
(mode & ~user_mask) | (user_mask & mode_mask)
|
||||
when '+'
|
||||
mode | (user_mask & mode_mask)
|
||||
when '-'
|
||||
mode & ~(user_mask & mode_mask)
|
||||
end
|
||||
mask
|
||||
end
|
||||
private_module_function :mode_mask
|
||||
private_module_function :apply_mask
|
||||
|
||||
def symbolic_modes_to_i(modes, path) #:nodoc:
|
||||
current_mode = (File.stat(path).mode & 07777)
|
||||
modes.split(/,/).inject(0) do |mode, mode_sym|
|
||||
mode_sym = "a#{mode_sym}" if mode_sym =~ %r!^[=+-]!
|
||||
target, mode = mode_sym.split %r![=+-]!
|
||||
def symbolic_modes_to_i(mode_sym, path) #:nodoc:
|
||||
mode_sym.split(/,/).inject(File.stat(path).mode & 07777) do |current_mode, clause|
|
||||
target, *actions = clause.split(/([=+-])/)
|
||||
raise ArgumentError, "invalid file mode: #{mode_sym}" if actions.empty?
|
||||
target = 'a' if target.empty?
|
||||
user_mask = user_mask(target)
|
||||
mode_mask = mode_mask(mode ? mode : "", path)
|
||||
actions.each_slice(2) do |op, perm|
|
||||
need_apply = op == '='
|
||||
mode_mask = (perm || '').each_char.inject(0) do |mask, chr|
|
||||
case chr
|
||||
when "r"
|
||||
mask | 0444
|
||||
when "w"
|
||||
mask | 0222
|
||||
when "x"
|
||||
mask | 0111
|
||||
when "X"
|
||||
if FileTest.directory? path
|
||||
mask | 0111
|
||||
else
|
||||
mask
|
||||
end
|
||||
when "s"
|
||||
mask | 06000
|
||||
when "t"
|
||||
mask | 01000
|
||||
when "u", "g", "o"
|
||||
if mask.nonzero?
|
||||
current_mode = apply_mask(current_mode, user_mask, op, mask)
|
||||
end
|
||||
need_apply = false
|
||||
copy_mask = user_mask(chr)
|
||||
(current_mode & copy_mask) / (copy_mask & 0111) * (user_mask & 0111)
|
||||
else
|
||||
raise ArgumentError, "invalid `perm' symbol in file mode: #{chr}"
|
||||
end
|
||||
end
|
||||
|
||||
case mode_sym
|
||||
when /=/
|
||||
current_mode &= ~(user_mask)
|
||||
current_mode |= user_mask & mode_mask
|
||||
when /\+/
|
||||
current_mode |= user_mask & mode_mask
|
||||
when /-/
|
||||
current_mode &= ~(user_mask & mode_mask)
|
||||
if mode_mask.nonzero? || need_apply
|
||||
current_mode = apply_mask(current_mode, user_mask, op, mode_mask)
|
||||
end
|
||||
end
|
||||
current_mode
|
||||
end
|
||||
end
|
||||
private_module_function :symbolic_modes_to_i
|
||||
|
|
|
@ -932,6 +932,12 @@ class TestFileUtils
|
|||
check_singleton :chmod
|
||||
|
||||
touch 'tmp/a'
|
||||
chmod "u=wrx,g=rx,o=x", 'tmp/a'
|
||||
assert_equal 0751, File.stat('tmp/a').mode & 07777
|
||||
chmod "g+w-x", 'tmp/a'
|
||||
assert_equal 0761, File.stat('tmp/a').mode & 07777
|
||||
chmod "o+r,g=o+w,o-r,u-o", 'tmp/a' # 761 => 763 => 773 => 771 => 671
|
||||
assert_equal 0671, File.stat('tmp/a').mode & 07777
|
||||
chmod "u=wrx,g=,o=", 'tmp/a'
|
||||
assert_equal 0700, File.stat('tmp/a').mode & 0777
|
||||
chmod "u=rx,go=", 'tmp/a'
|
||||
|
@ -956,6 +962,26 @@ class TestFileUtils
|
|||
assert_equal 0500, File.stat('tmp/a').mode & 07777
|
||||
end
|
||||
|
||||
assert_raises_with_message(ArgumentError, /invalid\b.*\bfile mode/) {
|
||||
chmod "a", 'tmp/a'
|
||||
}
|
||||
|
||||
assert_raises_with_message(ArgumentError, /invalid\b.*\bfile mode/) {
|
||||
chmod "x+a", 'tmp/a'
|
||||
}
|
||||
|
||||
assert_raises_with_message(ArgumentError, /invalid\b.*\bfile mode/) {
|
||||
chmod "u+z", 'tmp/a'
|
||||
}
|
||||
|
||||
assert_raises_with_message(ArgumentError, /invalid\b.*\bfile mode/) {
|
||||
chmod ",+x", 'tmp/a'
|
||||
}
|
||||
|
||||
assert_raises_with_message(ArgumentError, /invalid\b.*\bfile mode/) {
|
||||
chmod "755", 'tmp/a'
|
||||
}
|
||||
|
||||
end if have_file_perm?
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue