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

This commit is contained in:
Nobuyoshi Nakada 2019-09-02 15:08:53 +09:00 коммит произвёл GitHub
Родитель 633ae3278e
Коммит 6f206b8ec6
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 23 добавлений и 28 удалений

7
NEWS
Просмотреть файл

@ -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]

31
dir.c
Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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

Просмотреть файл

@ -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,