Bug #7373

FileUtils#chmod verbose gives error when mode is string

Added by Ary Borenszweig over 1 year ago. Updated about 1 year ago.

[ruby-core:49427]
Status:Closed
Priority:Normal
Assignee:Yusuke Endoh
Category:lib
Target version:2.0.0
ruby -v:ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-darwin12.0.0] Backport:

Description

I can see the wrong code in trunk, even though it happened in 1.9.3p194: https://github.com/ruby/ruby/blob/trunk/lib/fileutils.rb#L1037 )

asterite @ ~ $ irb
irb(main):001:0> require 'fileutils'
=> true
irb(main):002:0> FileUtils.chmod '+x', 'foo'
=> ["foo"]
irb(main):003:0> FileUtils.chmod '+x', 'foo', verbose: true
ArgumentError: invalid value for Integer(): "+x"
from /Users/asterite/.rbenv/versions/1.9.3-p194/lib/ruby/1.9.1/fileutils.rb:967:in sprintf'
from /Users/asterite/.rbenv/versions/1.9.3-p194/lib/ruby/1.9.1/fileutils.rb:967:in
chmod'
from (irb):3
from /Users/asterite/.rbenv/versions/1.9.3-p194/bin/irb:12:in `'

This is because chmod in verbose mode assumes the mode is a number, and tries to format it in octal:

fu_output_message sprintf('chmod %o %s', mode, list.join(' ')) if options[:verbose]

The same problem is present in chmod_R.

Sorry I don't include a patch, I'm not sure how to solve it. Maybe check if mode is a number and then use %o, else use %s.

History

#1 Updated by Yusuke Endoh over 1 year ago

  • Status changed from Open to Assigned
  • Assignee set to Yusuke Endoh
  • Target version set to 2.0.0

Thank you.
I'll apply the following patch unless there is objection.

diff --git a/lib/fileutils.rb b/lib/fileutils.rb
index af2d19a..57ab0cf 100644
--- a/lib/fileutils.rb
+++ b/lib/fileutils.rb
@@ -996,6 +996,10 @@ private
mode.isa?(String) ? symbolicmodestoi(mode, path) : mode
end

  • def modetos(mode) #:nodoc:
  • mode.is_a?(String) ? mode : "%o" % mode
  • end
    +
    public

    #
    @@ -1034,7 +1038,7 @@ public
    def chmod(mode, list, options = {})
    fucheckoptions options, OPTTABLE['chmod']
    list = fu
    list(list)

  • fuoutputmessage sprintf('chmod %o %s', mode, list.join(' ')) if options[:verbose]

  • fuoutputmessage sprintf('chmod %s %s', modetos(mode), list.join(' ')) if options[:verbose]
    return if options[:noop]
    list.each do |path|
    Entry.new(path).chmod(fumode(mode, path))
    @@ -1055,9 +1059,9 @@ public
    def chmodR(mode, list, options = {})
    fu
    checkoptions options, OPTTABLE['chmodR']
    list = fu
    list(list)

  • fuoutputmessage sprintf('chmod -R%s %o %s',

  • fuoutputmessage sprintf('chmod -R%s %s %s',
    (options[:force] ? 'f' : ''),

  •                          mode, list.join(' ')) if options[:verbose]
    
  •                          mode_to_s(mode), list.join(' ')) if options[:verbose]
    

    return if options[:noop]
    list.each do |root|
    Entry_.new(root).traverse do |ent|

Yusuke Endoh mame@tsg.ne.jp

#2 Updated by Yusuke Endoh about 1 year ago

  • Status changed from Assigned to Closed

Applied at r39011.

Yusuke Endoh mame@tsg.ne.jp

Also available in: Atom PDF