The to_regexp method in utils/glob.rb has a parsing bug on the first line of its body that breaks every glob pattern containing braces.
Line 16 of utils/glob.rb:
curlies = 0, escaping = false
Ruby parses this as a multi-value rvalue assignment to a single lvalue, equivalent to curlies = [0, false]. The local curlies is an Array, not an Integer. The intent was two separate statements.
The consequence is that any glob containing { reaches curlies.positive? on line 33 and raises NoMethodError: undefined method 'positive?' for Array. A glob containing two { would also crash on curlies += 1 (TypeError: no implicit conversion of Integer into Array). Existing tests in test/ do not exercise brace expansion, so the defect has stayed latent. A pattern like **/*.{rb,js} passed through --exclude or --include is enough to reproduce.
A secondary defect in the same method compounds the problem. The return char on lines 21, 35, and 37 lives inside the chars.map do |char| ... end block, so it returns from to_regexp itself rather than the block. Once the method hits an escaped char, an unmatched }, or a closed brace at the right depth, it returns a single character instead of the assembled regexp string. The intended block-local value would be next char (or simply char as the block's last expression).
Fix direction: replace the multi-value line with two assignments, and replace the three return char statements with next char so the map continues across all characters.
curlies = 0
escaping = false
The
to_regexpmethod inutils/glob.rbhas a parsing bug on the first line of its body that breaks every glob pattern containing braces.Line 16 of
utils/glob.rb:Ruby parses this as a multi-value rvalue assignment to a single lvalue, equivalent to
curlies = [0, false]. The localcurliesis anArray, not anInteger. The intent was two separate statements.The consequence is that any glob containing
{reachescurlies.positive?on line 33 and raisesNoMethodError: undefined method 'positive?' for Array. A glob containing two{would also crash oncurlies += 1(TypeError: no implicit conversion of Integer into Array). Existing tests intest/do not exercise brace expansion, so the defect has stayed latent. A pattern like**/*.{rb,js}passed through--excludeor--includeis enough to reproduce.A secondary defect in the same method compounds the problem. The
return charon lines 21, 35, and 37 lives inside thechars.map do |char| ... endblock, so it returns fromto_regexpitself rather than the block. Once the method hits an escaped char, an unmatched}, or a closed brace at the right depth, it returns a single character instead of the assembled regexp string. The intended block-local value would benext char(or simplycharas the block's last expression).Fix direction: replace the multi-value line with two assignments, and replace the three
return charstatements withnext charso the map continues across all characters.