Skip to content

Commit d41370a

Browse files
committed
Fix crash in Dir#each/each_child/scan when closed
If the Dir object is closed in the block of Dir#each/each_child/scan, then it will crash because dirp->dir will be a NULL pointer. The following script demonstrates the crash: d = Dir.open("/") d.each { d.close }
1 parent 0702754 commit d41370a

2 files changed

Lines changed: 13 additions & 0 deletions

File tree

‎dir.c‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,6 +1102,8 @@ dir_each_entry(VALUE dir, VALUE (*each)(VALUE, VALUE, struct dir_entry_args *),
11021102
.dp = dp,
11031103
};
11041104
(*each)(arg, path, &each_args);
1105+
/* the block may have closed dir */
1106+
if (!dirp->dir) dir_closed();
11051107
}
11061108
return dir;
11071109
}

‎test/ruby/test_dir.rb‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,17 @@ def test_close
237237
assert_raise(IOError) { d.read }
238238
end
239239

240+
def test_each_with_close
241+
d = Dir.open(@root)
242+
assert_raise(IOError) { d.each { d.close } }
243+
244+
d = Dir.open(@root)
245+
assert_raise(IOError) { d.each_child { d.close } }
246+
247+
d = Dir.open(@root)
248+
assert_raise(IOError) { d.scan { |*| d.close } }
249+
end
250+
240251
def test_glob
241252
assert_equal((%w(.) + ("a".."z").to_a).map{|f| File.join(@root, f) },
242253
Dir.glob(File.join(@root, "*"), File::FNM_DOTMATCH))

0 commit comments

Comments
 (0)