diff options
-rw-r--r-- | NEWS | 7 | ||||
-rw-r--r-- | dir.c | 31 | ||||
-rw-r--r-- | spec/ruby/core/dir/shared/glob.rb | 8 | ||||
-rw-r--r-- | test/ruby/test_dir.rb | 5 |
4 files changed, 23 insertions, 28 deletions
@@ -79,6 +79,13 @@ Complex:: * Added Complex#<=>. So 0 <=> 0i will not raise NoMethodError. [Bug #15857] +Dir:: + + Modified method:: + + * Dir#glob and Dir#[] no longer allow NUL-separated glob pattern. + Use Array instead. [Feature #14643] + Encoding:: * Added new encoding CESU-8 [Feature #15931] @@ -2694,41 +2694,24 @@ push_glob(VALUE ary, VALUE str, VALUE base, int flags) static VALUE rb_push_glob(VALUE str, VALUE base, int flags) /* '\0' is delimiter */ { - long offset = 0; - long len; VALUE ary; - int warned = FALSE; + int status; /* can contain null bytes as separators */ - if (!RB_TYPE_P((str), T_STRING)) { + if (!RB_TYPE_P(str, T_STRING)) { FilePathValue(str); } + else if (!rb_str_to_cstr(str)) { + rb_raise(rb_eArgError, "nul-separated glob pattern is deprecated"); + } else { rb_check_safe_obj(str); rb_enc_check(str, rb_enc_from_encoding(rb_usascii_encoding())); } ary = rb_ary_new(); - while (offset < (len = RSTRING_LEN(str))) { - int status; - long rest = len - offset; - const char *pbeg = RSTRING_PTR(str), *p = pbeg + offset; - const char *pend = memchr(p, '\0', rest); - if (pend) { - if (!warned) { - rb_warn("use glob patterns list instead of nul-separated patterns"); - warned = TRUE; - } - rest = ++pend - p; - offset = pend - pbeg; - } - else { - offset = len; - } - status = push_glob(ary, rb_str_subseq(str, p-pbeg, rest), - base, flags); - if (status) GLOB_JUMP_TAG(status); - } + status = push_glob(ary, str, base, flags); + if (status) GLOB_JUMP_TAG(status); return ary; } diff --git a/spec/ruby/core/dir/shared/glob.rb b/spec/ruby/core/dir/shared/glob.rb index e4ffb51286..62675145df 100644 --- a/spec/ruby/core/dir/shared/glob.rb +++ b/spec/ruby/core/dir/shared/glob.rb @@ -30,7 +30,7 @@ describe :dir_glob, shared: true do end end - ruby_version_is "2.6" do + ruby_version_is "2.6"..."2.7" do it "splits the string on \\0 if there is only one string given and warns" do -> { Dir.send(@method, "file_o*\0file_t*").should == @@ -39,6 +39,12 @@ describe :dir_glob, shared: true do end end + ruby_version_is "2.7" do + it "raises an ArgumentError if the string contains \\0" do + -> {Dir.send(@method, "file_o*\0file_t*")}.should raise_error ArgumentError, /nul-separated/ + end + end + it "matches non-dotfiles with '*'" do expected = %w[ brace diff --git a/test/ruby/test_dir.rb b/test/ruby/test_dir.rb index 93ae3c3ed9..75cae71093 100644 --- a/test/ruby/test_dir.rb +++ b/test/ruby/test_dir.rb @@ -138,9 +138,8 @@ class TestDir < Test::Unit::TestCase Dir.glob(File.join(@root, "*"), File::FNM_DOTMATCH).sort) assert_equal([@root] + ("a".."z").map {|f| File.join(@root, f) }.sort, Dir.glob([@root, File.join(@root, "*")]).sort) - assert_warning(/nul-separated patterns/) do - assert_equal([@root] + ("a".."z").map {|f| File.join(@root, f) }.sort, - Dir.glob(@root + "\0\0\0" + File.join(@root, "*")).sort) + assert_raise_with_message(ArgumentError, /nul-separated/) do + Dir.glob(@root + "\0\0\0" + File.join(@root, "*")) end assert_equal(("a".."z").step(2).map {|f| File.join(File.join(@root, f), "") }.sort, |