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
This commit is contained in:
nobu 2018-04-19 07:05:39 +00:00
parent ae92a9e4ed
commit c635662d7f
4 changed files with 19 additions and 5 deletions

5
NEWS
View File

@ -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 and File.readlines do not invoke external commands even if the path
starts with the pipe character |. [Feature #14245] 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) === Stdlib compatibility issues (excluding feature bug fixes)
=== C API updates === C API updates

5
dir.c
View File

@ -2536,6 +2536,7 @@ rb_push_glob(VALUE str, VALUE base, int flags) /* '\0' is delimiter */
long offset = 0; long offset = 0;
long len; long len;
VALUE ary; VALUE ary;
int warned = FALSE;
/* can contain null bytes as separators */ /* can contain null bytes as separators */
if (!RB_TYPE_P((str), T_STRING)) { 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 *pbeg = RSTRING_PTR(str), *p = pbeg + offset;
const char *pend = memchr(p, '\0', rest); const char *pend = memchr(p, '\0', rest);
if (pend) { if (pend) {
if (!warned) {
rb_warn("use glob patterns list instead of nul-separated patterns");
warned = TRUE;
}
rest = ++pend - p; rest = ++pend - p;
offset = pend - pbeg; offset = pend - pbeg;
} }

View File

@ -25,9 +25,11 @@ describe :dir_glob, shared: true do
Dir.send(@method, obj).should == %w[file_one.ext] Dir.send(@method, obj).should == %w[file_one.ext]
end end
it "splits the string on \\0 if there is only one string given" do ruby_version_is ""..."2.6" do
Dir.send(@method, "file_o*\0file_t*").should == it "splits the string on \\0 if there is only one string given" do
%w!file_one.ext file_two.ext! Dir.send(@method, "file_o*\0file_t*").should ==
%w!file_one.ext file_two.ext!
end
end end
it "matches non-dotfiles with '*'" do it "matches non-dotfiles with '*'" do

View File

@ -136,8 +136,10 @@ class TestDir < Test::Unit::TestCase
Dir.glob(File.join(@root, "*"), File::FNM_DOTMATCH).sort) Dir.glob(File.join(@root, "*"), File::FNM_DOTMATCH).sort)
assert_equal([@root] + ("a".."z").map {|f| File.join(@root, f) }.sort, assert_equal([@root] + ("a".."z").map {|f| File.join(@root, f) }.sort,
Dir.glob([@root, File.join(@root, "*")]).sort) Dir.glob([@root, File.join(@root, "*")]).sort)
assert_equal([@root] + ("a".."z").map {|f| File.join(@root, f) }.sort, assert_warning(/nul-separated patterns/) do
Dir.glob(@root + "\0\0\0" + 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)
end
assert_equal(("a".."z").step(2).map {|f| File.join(File.join(@root, f), "") }.sort, assert_equal(("a".."z").step(2).map {|f| File.join(File.join(@root, f), "") }.sort,
Dir.glob(File.join(@root, "*/")).sort) Dir.glob(File.join(@root, "*/")).sort)