ruby-changes:61689
From: Nobuyoshi <ko1@a...>
Date: Fri, 12 Jun 2020 18:46:29 +0900 (JST)
Subject: [ruby-changes:61689] cc9ca468fe (master): [ruby/fileutils] Fix #install with "X" mode option
https://git.ruby-lang.org/ruby.git/commit/?id=cc9ca468fe From cc9ca468fecd153596c25877006f208161e477fb Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada <nobu@r...> Date: Thu, 3 Oct 2019 01:39:02 +0900 Subject: [ruby/fileutils] Fix #install with "X" mode option `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. https://github.com/ruby/fileutils/commit/af675af6b2 diff --git a/lib/fileutils.rb b/lib/fileutils.rb index 56b0c1a..fea954e 100644 --- a/lib/fileutils.rb +++ b/lib/fileutils.rb @@ -917,11 +917,8 @@ module FileUtils https://github.com/ruby/ruby/blob/trunk/lib/fileutils.rb#L917 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? @@ -938,7 +935,7 @@ module FileUtils https://github.com/ruby/ruby/blob/trunk/lib/fileutils.rb#L935 when "x" mask | 0111 when "X" - if FileTest.directory? path + if path.directory? mask | 0111 else mask diff --git a/test/fileutils/test_fileutils.rb b/test/fileutils/test_fileutils.rb index e9a21be..d785de4 100644 --- a/test/fileutils/test_fileutils.rb +++ b/test/fileutils/test_fileutils.rb @@ -1193,6 +1193,8 @@ class TestFileUtils < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/fileutils/test_fileutils.rb#L1193 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_equal_filemode 'tmp/a', 'tmp/l' end if have_file_perm? def test_chmod -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/