Skip to content

Commit 84663b1

Browse files
committed
Fix UTF-16 autocompletion
fixes #52
1 parent 50db8f8 commit 84663b1

File tree

2 files changed

+27
-2
lines changed

2 files changed

+27
-2
lines changed

lib/irb/completion.rb

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ def retrieve_completion_data(input, bind:, doc_namespace:)
275275
nil
276276
else
277277
sym = $1
278-
candidates = Symbol.all_symbols.collect do |s|
278+
candidates = Symbol.all_symbols.filter_map do |s|
279279
s.inspect
280280
rescue EncodingError
281281
# ignore
@@ -453,6 +453,15 @@ def retrieve_completion_data(input, bind:, doc_namespace:)
453453
else
454454
candidates = (bind.eval_methods | bind.eval_private_methods | bind.local_variables | bind.eval_instance_variables | bind.eval_class_constants).collect{|m| m.to_s}
455455
candidates |= RubyLex::RESERVED_WORDS.map(&:to_s)
456+
457+
target_encoding = Encoding.default_external
458+
candidates = candidates.compact.filter_map do |candidate|
459+
converted = candidate.encoding == target_encoding ? candidate : candidate.encode(target_encoding)
460+
# Remove BOM (U+FEFF) which may be preserved when converting from UTF-16
461+
converted.delete("\uFEFF")
462+
rescue EncodingError
463+
nil
464+
end
456465
candidates.grep(/^#{Regexp.quote(input)}/).sort
457466
end
458467
end

test/irb/test_completion.rb

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ def test_complete_require_with_pathname_in_load_path
110110
FileUtils.remove_entry(temp_dir) if temp_dir
111111
end
112112

113-
def test_complete_require_with_string_convertable_in_load_path
113+
def test_complete_require_with_string_convertible_in_load_path
114114
temp_dir = Dir.mktmpdir
115115
File.write(File.join(temp_dir, "foo.rb"), "test")
116116
object = Object.new
@@ -343,5 +343,21 @@ def test_regexp_completor_handles_encoding_errors_gracefully
343343
Encoding.default_external = original_encoding
344344
end
345345
end
346+
347+
def test_utf16_method_name_does_not_crash
348+
# Reproduces issue #52: https://github.com/ruby/irb/issues/52
349+
method_name = "test_utf16_method".encode(Encoding::UTF_16)
350+
test_obj = Object.new
351+
test_obj.define_singleton_method(method_name) {}
352+
test_bind = test_obj.instance_eval { binding }
353+
354+
completor = IRB::RegexpCompletor.new
355+
result = nil
356+
assert_nothing_raised do
357+
result = completor.completion_candidates('', 'test', '', bind: test_bind)
358+
end
359+
360+
assert_include result, "test_utf16_method"
361+
end
346362
end
347363
end

0 commit comments

Comments
 (0)