Dir#glob and Dir#[] no longer allow NUL-separated glob pattern in Ruby 2.7


Dir#glob and Dir#[] return an array of matching filenames depending upon the parameter.

Example

2.6.5 :001 > Dir.glob("foo.txt")
 => ["foo.txt"]
2.6.5 :002 > Dir.glob(["foo.txt", "test.rb"])
 => ["foo.txt", "test.rb"]

Before

With Dir#glob and Dir#[], there is a possibility of unintended file operations because they do not check NULL characters.

2.6.5 :001 > Dir.glob("foo.*\0bar.*")
(irb):1: warning: use glob patterns list instead of nul-separated patterns
 => ["foo.txt", "bar.txt"]
2.6.5 :002 > 
2.6.5 :003 > Dir["index.html\0show.html"]
(irb):2: warning: use glob patterns list instead of nul-separated patterns
 => ["index.html", "show.html"]

In the first example above, the NUL-separated glob pattern foo.*\0bar.* unexpectedly matches the files based on the patterns foo.* and bar.*.

The warning that we can notice above, use glob patterns list instead of nul-separated patterns suggests that we use an array of glob patterns instead of a NUL-separated string.

Ruby 2.7

Ruby 2.7 prohibits NUL-separated glob pattern.

A check has been added in this update that raises an ArgumentError if the parameter string contains \0.

2.7.0-preview2 :001 > Dir.glob("foo.*\0bar.*")
Traceback (most recent call last):
        5: from /Users/dexter/.rvm/rubies/ruby-head/bin/irb:23:in `<main>'
        4: from /Users/dexter/.rvm/rubies/ruby-head/bin/irb:23:in `load'
        3: from /Users/dexter/.rvm/rubies/ruby-head/lib/ruby/gems/2.7.0/gems/irb-1.1.0.pre.3/exe/irb:11:in `<top (required)>'
        2: from (irb):1
        1: from (irb):1:in `glob'
ArgumentError (nul-separated glob pattern is deprecated)    
2.7.0-preview2 :002 > 
2.7.0-preview2 :003 >  Dir["index.html\0show.html"]
Traceback (most recent call last):
        6: from /Users/dexter/.rvm/rubies/ruby-head/bin/irb:23:in `<main>'
        5: from /Users/dexter/.rvm/rubies/ruby-head/bin/irb:23:in `load'
        4: from /Users/dexter/.rvm/rubies/ruby-head/lib/ruby/gems/2.7.0/gems/irb-1.1.0.pre.3/exe/irb:11:in `<top (required)>'
        3: from (irb):2
        2: from (irb):3:in `rescue in irb_binding'
        1: from (irb):3:in `[]'
ArgumentError (nul-separated glob pattern is deprecated)

As we can see, using a NUL-separated string as parameter to Dir#glob or Dir#[] results in an ArgumentError.

Instead, we should use an array of glob patterns as the parameter.

Example

2.7.0-preview2 :001 > Dir.glob(["foo.*","bar.*"])
 => ["foo.txt", "bar.txt"]

Above example makes use of an array of glob patterns.