ruby-changes:57484
From: Nobuyoshi <ko1@a...>
Date: Mon, 2 Sep 2019 15:09:12 +0900 (JST)
Subject: [ruby-changes:57484] 6f206b8ec6 (master): Prohibit nul-separated glob pattern [Feature #14643] (#2419)
https://git.ruby-lang.org/ruby.git/commit/?id=6f206b8ec6 From 6f206b8ec6f945804c56cf8249739c6e94ed65f6 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada <nobu@r...> Date: Mon, 2 Sep 2019 15:08:53 +0900 Subject: Prohibit nul-separated glob pattern [Feature #14643] (#2419) diff --git a/NEWS b/NEWS index 2857cc9..7100394 100644 --- a/NEWS +++ b/NEWS @@ -79,6 +79,13 @@ Complex:: https://github.com/ruby/ruby/blob/trunk/NEWS#L79 * 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] diff --git a/dir.c b/dir.c index bfd085e..f5cc42d 100644 --- a/dir.c +++ b/dir.c @@ -2694,41 +2694,24 @@ push_glob(VALUE ary, VALUE str, VALUE base, int flags) https://github.com/ruby/ruby/blob/trunk/dir.c#L2694 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 e4ffb51..6267514 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 https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/dir/shared/glob.rb#L30 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 https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/dir/shared/glob.rb#L39 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 93ae3c3..75cae71 100644 --- a/test/ruby/test_dir.rb +++ b/test/ruby/test_dir.rb @@ -138,9 +138,8 @@ class TestDir < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_dir.rb#L138 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, -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/