Skip to content

Commit 26a1d04

Browse files
committed
Fix methods defined with invalid encoding are not displayed in completion
1 parent 29cdd26 commit 26a1d04

2 files changed

Lines changed: 48 additions & 2 deletions

File tree

lib/irb/completion.rb

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,8 +193,15 @@ def completion_candidates(preposing, target, postposing, bind:)
193193

194194
# It doesn't make sense to propose commands with other preposing
195195
commands = [] unless preposing.empty?
196-
197-
completion_data = retrieve_completion_data(target, bind: bind, doc_namespace: false).compact.map{ |i| i.encode(Encoding.default_external) }
196+
@encoding_warning_shown ||= false
197+
198+
completion_data = retrieve_completion_data(target, bind: bind, doc_namespace: false).compact.map do |i|
199+
i.encode(Encoding.default_external)
200+
rescue Encoding::UndefinedConversionError
201+
warn "Warning: Invalid encoding in method name '#{i}'. can't be converted to the locale #{Encoding.default_external}." unless @encoding_warning_shown
202+
@encoding_warning_shown = true
203+
nil
204+
end.compact
198205
commands | completion_data
199206
end
200207

test/irb/test_completion.rb

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,4 +314,43 @@ def test_retrieve_completion_data
314314
assert_equal(IRB::InputCompletor.retrieve_completion_data('a.abs', bind: bind, doc_namespace: true), 'Integer.abs')
315315
end
316316
end
317+
318+
class InvalidEncodingMethodTest < TestCase
319+
def test_invalid_encoding_method_warning
320+
invalid_method_name = "b\xff".force_encoding(Encoding::ASCII_8BIT)
321+
322+
test_obj = Object.new
323+
test_obj.define_singleton_method(invalid_method_name) {}
324+
test_bind = test_obj.instance_eval { binding }
325+
326+
original_stderr = $stderr
327+
original_encoding = Encoding.default_external
328+
original_verbose = $VERBOSE
329+
330+
begin
331+
stderr_buffer = StringIO.new
332+
$stderr = stderr_buffer
333+
$VERBOSE = nil
334+
Encoding.default_external = Encoding::UTF_8
335+
$VERBOSE = original_verbose
336+
337+
completor = IRB::RegexpCompletor.new
338+
result = completor.completion_candidates('', 'b', '', bind: test_bind)
339+
340+
assert_equal("Warning: Invalid encoding in method name 'b\xff'. can't be converted to the locale UTF-8.\n".force_encoding(Encoding::ASCII_8BIT), stderr_buffer.string.force_encoding(Encoding::ASCII_8BIT))
341+
assert_not_include(result, nil)
342+
343+
stderr_buffer.truncate(0)
344+
stderr_buffer.rewind
345+
stderr_buffer = StringIO.new
346+
347+
completor.completion_candidates('', 'b', '', bind: test_bind)
348+
assert_empty(stderr_buffer.string)
349+
ensure
350+
$stderr = original_stderr
351+
Encoding.default_external = original_encoding
352+
$VERBOSE = original_verbose
353+
end
354+
end
355+
end
317356
end

0 commit comments

Comments
 (0)