@@ -276,7 +276,7 @@ class File < IO::FileDescriptor
276
276
elsif '?' === g && @path_index < path.size
277
277
if ! separators.includes?(path[@path_index ].unsafe_chr)
278
278
@glob_index += 1
279
- @path_index += 1
279
+ _, @path_index = consume_unicode_character(path_str, @path_index )
280
280
next
281
281
end
282
282
elsif '[' === g && @path_index < path.size
@@ -293,25 +293,17 @@ class File < IO::FileDescriptor
293
293
first = true
294
294
is_match = false
295
295
296
- c = path[ @path_index ]
296
+ c, new_path_index = consume_unicode_glob_character(path_str, @path_index )
297
297
298
298
while @glob_index < glob.size && (first || ! (']' === glob[@glob_index ]))
299
- low = glob[@glob_index ]
300
- if ! unescape(pointerof (low), glob, pointerof (@glob_index ))
301
- raise File ::BadPatternError .new(" Invalid pattern" )
302
- end
303
- @glob_index += 1
299
+ low, @glob_index = consume_unicode_glob_character(glob_str, @glob_index )
304
300
305
301
# If there is a - and the following character is not ], read the range end character.
306
302
if @glob_index + 1 < glob.size &&
307
303
glob[@glob_index ] === '-' &&
308
304
! (glob[@glob_index + 1 ] === ']' )
309
305
@glob_index += 1
310
- high = glob[@glob_index ]
311
- if ! unescape(pointerof (high), glob, pointerof (@glob_index ))
312
- raise File ::BadPatternError .new(" Invalid pattern" )
313
- end
314
- @glob_index += 1
306
+ high, @glob_index = consume_unicode_glob_character(glob_str, @glob_index )
315
307
else
316
308
high = low
317
309
end
@@ -327,7 +319,7 @@ class File < IO::FileDescriptor
327
319
end
328
320
@glob_index += 1
329
321
if is_match != negated_class
330
- @path_index += 1
322
+ @path_index = new_path_index
331
323
next
332
324
end
333
325
elsif g === '{'
@@ -402,3 +394,24 @@ private def unescape(c, glob, glob_index) : Bool
402
394
403
395
true
404
396
end
397
+
398
+ @[AlwaysInline ]
399
+ private def consume_unicode_character (string , index ) : {Char , UInt64 }
400
+ reader = Char ::Reader .new(string, index)
401
+ {reader.current_char, index + reader.current_char_width}
402
+ end
403
+
404
+ @[AlwaysInline ]
405
+ private def consume_unicode_glob_character (string , index ) : {Char , UInt64 }
406
+ c = string.to_unsafe[index]
407
+
408
+ if ! unescape(pointerof (c), string.to_slice, pointerof (index))
409
+ raise File ::BadPatternError .new(" Invalid pattern" )
410
+ end
411
+
412
+ if c < 0x80
413
+ {c.unsafe_chr, index + 1 }
414
+ else
415
+ consume_unicode_character(string, index)
416
+ end
417
+ end
0 commit comments