1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

[ruby/fileutils] Narrow the scope of ensure

The ensure in postorder_traverse was added for [Bug #6756].
The intention was to try to delete the parent directory if it failed to
get the children. (It may be possible to delete the directory if it is
empty.)

However, the ensure region rescue'ed not only "failure to get children"
but also "failure to delete each child". Thus, the following raised
Errno::ENOTEMPTY, but we expect it to raise Errno::EACCES.

```
$ mkdir foo
$ touch foo/bar
$ chmod 555 foo
$ ruby -rfileutils -e 'FileUtils.rm_rf("foo")'
```

This changeset narrows the ensure region so that it rescues only
"failure to get children".

https://github.com/ruby/fileutils/commit/ec5d3b84ea
This commit is contained in:
Yusuke Endoh 2022-07-26 21:23:47 +09:00 committed by git
parent 073f3b7e0a
commit 96562a517d
2 changed files with 28 additions and 2 deletions

View file

@ -2328,13 +2328,21 @@ module FileUtils
def postorder_traverse def postorder_traverse
if directory? if directory?
entries().each do |ent| begin
children = entries()
rescue Errno::EACCES
# Failed to get the list of children.
# Assuming there is no children, try to process the parent directory.
yield self
return
end
children.each do |ent|
ent.postorder_traverse do |e| ent.postorder_traverse do |e|
yield e yield e
end end
end end
end end
ensure
yield self yield self
end end

View file

@ -750,6 +750,24 @@ class TestFileUtils < Test::Unit::TestCase
assert_file_not_exist 'tmp/tmpdir3' assert_file_not_exist 'tmp/tmpdir3'
end end
def test_rm_r_no_permissions
check_singleton :rm_rf
return if /mswin|mingw/ =~ RUBY_PLATFORM
mkdir 'tmpdatadir'
touch 'tmpdatadir/tmpdata'
chmod "-x", 'tmpdatadir'
begin
assert_raise Errno::EACCES do
rm_r 'tmpdatadir'
end
ensure
chmod "+x", 'tmpdatadir'
end
end
def test_remove_entry_cjk_path def test_remove_entry_cjk_path
dir = "tmpdir\u3042" dir = "tmpdir\u3042"
my_rm_rf dir my_rm_rf dir