From c635662d7fb56dcf743c6bb32755904bc2914098 Mon Sep 17 00:00:00 2001 From: nobu Date: Thu, 19 Apr 2018 07:05:39 +0000 Subject: [PATCH] dir.c: warning for NUL * dir.c (rb_push_glob): warn NUL-separated glob patterns. [Feature #14643] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63190 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- NEWS | 5 +++++ dir.c | 5 +++++ spec/ruby/core/dir/shared/glob.rb | 8 +++++--- test/ruby/test_dir.rb | 6 ++++-- 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/NEWS b/NEWS index 5be9025862..5a8f4e4286 100644 --- a/NEWS +++ b/NEWS @@ -152,6 +152,11 @@ with all sufficient information, see the ChangeLog file or Redmine and File.readlines do not invoke external commands even if the path starts with the pipe character |. [Feature #14245] +* Dir + + * Dir.glob with '\0'-separated pattern list will be deprecated, and + is now warned. [Feature #14643] + === Stdlib compatibility issues (excluding feature bug fixes) === C API updates diff --git a/dir.c b/dir.c index a8e7f01d19..7bffb0cd27 100644 --- a/dir.c +++ b/dir.c @@ -2536,6 +2536,7 @@ rb_push_glob(VALUE str, VALUE base, int flags) /* '\0' is delimiter */ long offset = 0; long len; VALUE ary; + int warned = FALSE; /* can contain null bytes as separators */ if (!RB_TYPE_P((str), T_STRING)) { @@ -2553,6 +2554,10 @@ rb_push_glob(VALUE str, VALUE base, int flags) /* '\0' is delimiter */ 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; } diff --git a/spec/ruby/core/dir/shared/glob.rb b/spec/ruby/core/dir/shared/glob.rb index 40973995c1..2fe22ac6c3 100644 --- a/spec/ruby/core/dir/shared/glob.rb +++ b/spec/ruby/core/dir/shared/glob.rb @@ -25,9 +25,11 @@ describe :dir_glob, shared: true do Dir.send(@method, obj).should == %w[file_one.ext] end - it "splits the string on \\0 if there is only one string given" do - Dir.send(@method, "file_o*\0file_t*").should == - %w!file_one.ext file_two.ext! + ruby_version_is ""..."2.6" do + it "splits the string on \\0 if there is only one string given" do + Dir.send(@method, "file_o*\0file_t*").should == + %w!file_one.ext file_two.ext! + end end it "matches non-dotfiles with '*'" do diff --git a/test/ruby/test_dir.rb b/test/ruby/test_dir.rb index 7597262702..5323c764f5 100644 --- a/test/ruby/test_dir.rb +++ b/test/ruby/test_dir.rb @@ -136,8 +136,10 @@ 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_equal([@root] + ("a".."z").map {|f| File.join(@root, f) }.sort, - Dir.glob(@root + "\0\0\0" + 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) + end assert_equal(("a".."z").step(2).map {|f| File.join(File.join(@root, f), "") }.sort, Dir.glob(File.join(@root, "*/")).sort)