1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Prohibit nul-separated glob pattern [Feature #14643] (#2419)

This commit is contained in:
Nobuyoshi Nakada 2019-09-02 15:08:53 +09:00 committed by GitHub
parent 633ae3278e
commit 6f206b8ec6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
Notes: git 2019-09-02 15:09:16 +09:00
Merged-By: nobu <nobu@ruby-lang.org>
4 changed files with 23 additions and 28 deletions

7
NEWS
View file

@ -79,6 +79,13 @@ Complex::
* Added Complex#<=>. So 0 <=> 0i will not raise NoMethodError. [Bug #15857] * 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:: Encoding::
* Added new encoding CESU-8 [Feature #15931] * Added new encoding CESU-8 [Feature #15931]

29
dir.c
View file

@ -2694,41 +2694,24 @@ push_glob(VALUE ary, VALUE str, VALUE base, int flags)
static VALUE static VALUE
rb_push_glob(VALUE str, VALUE base, int flags) /* '\0' is delimiter */ rb_push_glob(VALUE str, VALUE base, int flags) /* '\0' is delimiter */
{ {
long offset = 0;
long len;
VALUE ary; VALUE ary;
int warned = FALSE; int status;
/* 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)) {
FilePathValue(str); FilePathValue(str);
} }
else if (!rb_str_to_cstr(str)) {
rb_raise(rb_eArgError, "nul-separated glob pattern is deprecated");
}
else { else {
rb_check_safe_obj(str); rb_check_safe_obj(str);
rb_enc_check(str, rb_enc_from_encoding(rb_usascii_encoding())); rb_enc_check(str, rb_enc_from_encoding(rb_usascii_encoding()));
} }
ary = rb_ary_new(); ary = rb_ary_new();
while (offset < (len = RSTRING_LEN(str))) { status = push_glob(ary, str, base, flags);
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); if (status) GLOB_JUMP_TAG(status);
}
return ary; return ary;
} }

View file

@ -30,7 +30,7 @@ describe :dir_glob, shared: true do
end end
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 it "splits the string on \\0 if there is only one string given and warns" do
-> { -> {
Dir.send(@method, "file_o*\0file_t*").should == Dir.send(@method, "file_o*\0file_t*").should ==
@ -39,6 +39,12 @@ describe :dir_glob, shared: true do
end end
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 it "matches non-dotfiles with '*'" do
expected = %w[ expected = %w[
brace brace

View file

@ -138,9 +138,8 @@ 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_warning(/nul-separated patterns/) do assert_raise_with_message(ArgumentError, /nul-separated/) do
assert_equal([@root] + ("a".."z").map {|f| File.join(@root, f) }.sort, Dir.glob(@root + "\0\0\0" + File.join(@root, "*"))
Dir.glob(@root + "\0\0\0" + File.join(@root, "*")).sort)
end 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,