The code assumed that /usr/share/dict/words did not use mixed
case, and it does at least on a few operating systems.
From CryptoRAT (Luke Elliot)
Fixes [Bug #16957]
`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.
af675af6b2
Setting class varibles goes through the ancestor list which can
contain iclasses. Iclasses share a lot of information with the
module they are made from, but not the frozen status.
Check the frozen status of the module instead of the iclass.
When `LANG=C`, dir is `UTF-8` and `base` is 'ASCII-8BIT` in `FileUtils::Entry_#join`.
So `Encoding::CompatibilityError` occurred and files are not removed.
20200611T060002Z.fail.html.gz
```
1) Error:
WEBrick::TestFileHandler#test_cjk_in_path:
Errno::ENOTEMPTY: Directory not empty @ dir_s_rmdir - /home/chkbuild/chkbuild/tmp/build/20200611T060002Z/tmp/???20200611-1887828-3nn72a
/home/chkbuild/chkbuild/tmp/build/20200611T060002Z/ruby/lib/fileutils.rb:1460:in `rmdir'
/home/chkbuild/chkbuild/tmp/build/20200611T060002Z/ruby/lib/fileutils.rb:1460:in `block in remove_dir1'
/home/chkbuild/chkbuild/tmp/build/20200611T060002Z/ruby/lib/fileutils.rb:1471:in `platform_support'
/home/chkbuild/chkbuild/tmp/build/20200611T060002Z/ruby/lib/fileutils.rb:1459:in `remove_dir1'
/home/chkbuild/chkbuild/tmp/build/20200611T060002Z/ruby/lib/fileutils.rb:1452:in `remove'
/home/chkbuild/chkbuild/tmp/build/20200611T060002Z/ruby/lib/fileutils.rb:780:in `block in remove_entry'
/home/chkbuild/chkbuild/tmp/build/20200611T060002Z/ruby/lib/fileutils.rb:1509:in `ensure in postorder_traverse'
/home/chkbuild/chkbuild/tmp/build/20200611T060002Z/ruby/lib/fileutils.rb:1509:in `postorder_traverse'
/home/chkbuild/chkbuild/tmp/build/20200611T060002Z/ruby/lib/fileutils.rb:778:in `remove_entry'
/home/chkbuild/chkbuild/tmp/build/20200611T060002Z/ruby/lib/tmpdir.rb:97:in `mktmpdir'
/home/chkbuild/chkbuild/tmp/build/20200611T060002Z/ruby/test/webrick/test_filehandler.rb:292:in `test_cjk_in_path'
```
This callcache is on stack, must not be GCed. However its contents are
copied from other materials, which can be an ordinal object. Should
set a flag to make sure it is properly skipped by the GC.