Skip to content

Commit

Permalink
Fix #install with "X" mode option
Browse files Browse the repository at this point in the history
`FileUtils#install` methed raises an unexpected `TypeError`, when
called with `mode:` option which has `"X"`.

```
$ ruby -rfileutils -e 'FileUtils.install("tmp/a", "tmp/b", mode: "o+X")'
/opt/local/lib/ruby/2.7.0/fileutils.rb:942:in `directory?': no implicit conversion of File::Stat into String (TypeError)
	from /opt/local/lib/ruby/2.7.0/fileutils.rb:942:in `block (3 levels) in symbolic_modes_to_i'
	from /opt/local/lib/ruby/2.7.0/fileutils.rb:933:in `each_char'
	from /opt/local/lib/ruby/2.7.0/fileutils.rb:933:in `each'
	from /opt/local/lib/ruby/2.7.0/fileutils.rb:933:in `inject'
	from /opt/local/lib/ruby/2.7.0/fileutils.rb:933:in `block (2 levels) in symbolic_modes_to_i'
	from /opt/local/lib/ruby/2.7.0/fileutils.rb:931:in `each'
	from /opt/local/lib/ruby/2.7.0/fileutils.rb:931:in `each_slice'
	from /opt/local/lib/ruby/2.7.0/fileutils.rb:931:in `block in symbolic_modes_to_i'
	from /opt/local/lib/ruby/2.7.0/fileutils.rb:926:in `each'
	from /opt/local/lib/ruby/2.7.0/fileutils.rb:926:in `inject'
	from /opt/local/lib/ruby/2.7.0/fileutils.rb:926:in `symbolic_modes_to_i'
	from /opt/local/lib/ruby/2.7.0/fileutils.rb:973:in `fu_mode'
	from /opt/local/lib/ruby/2.7.0/fileutils.rb:883:in `block in install'
	from /opt/local/lib/ruby/2.7.0/fileutils.rb:1588:in `block in fu_each_src_dest'
	from /opt/local/lib/ruby/2.7.0/fileutils.rb:1604:in `fu_each_src_dest0'
	from /opt/local/lib/ruby/2.7.0/fileutils.rb:1586:in `fu_each_src_dest'
	from /opt/local/lib/ruby/2.7.0/fileutils.rb:877:in `install'
	from -e:1:in `<main>'
```

In spite of that `symbolic_modes_to_i` considers the `File::Stat`
`path` case at the beginning, in `"X"` case, `path` is passed to
`FileTest.directory?` method which requires a `String`.  In such
case, the mode in `path` should be examined instead.
  • Loading branch information
nobu committed Oct 2, 2019
1 parent bb10efe commit 2ea54ad
Show file tree
Hide file tree
Showing 2 changed files with 5 additions and 6 deletions.
9 changes: 3 additions & 6 deletions lib/fileutils.rb
Expand Up @@ -918,11 +918,8 @@ def apply_mask(mode, user_mask, op, mode_mask) #:nodoc:
private_module_function :apply_mask

def symbolic_modes_to_i(mode_sym, path) #:nodoc:
mode = if File::Stat === path
path.mode
else
File.stat(path).mode
end
path = File.stat(path) unless File::Stat === path
mode = path.mode
mode_sym.split(/,/).inject(mode & 07777) do |current_mode, clause|
target, *actions = clause.split(/([=+-])/)
raise ArgumentError, "invalid file mode: #{mode_sym}" if actions.empty?
Expand All @@ -939,7 +936,7 @@ def symbolic_modes_to_i(mode_sym, path) #:nodoc:
when "x"
mask | 0111
when "X"
if FileTest.directory? path
if path.directory?
mask | 0111
else
mask
Expand Down
2 changes: 2 additions & 0 deletions test/fileutils/test_fileutils.rb
Expand Up @@ -1182,6 +1182,8 @@ def test_install_mode_option
assert_filemode 04500, 'tmp/j'
install 'tmp/j', 'tmp/k', :mode => "+s"
assert_filemode 06500, 'tmp/k'
install 'tmp/a', 'tmp/l', :mode => "o+X"
assert_filemode 0644, 'tmp/l'
end if have_file_perm?

def test_chmod
Expand Down

0 comments on commit 2ea54ad

Please sign in to comment.