Skip to content

Commit 04d2cf5

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

2 files changed

Lines changed: 52 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: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,4 +314,47 @@ 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+
if RUBY_ENGINE == 'truffleruby'
321+
omit "TruffleRuby does not support invalid encoding methods."
322+
end
323+
324+
invalid_method_name = "b\xff".force_encoding(Encoding::ASCII_8BIT)
325+
326+
test_obj = Object.new
327+
test_obj.define_singleton_method(invalid_method_name) {}
328+
test_bind = test_obj.instance_eval { binding }
329+
330+
original_stderr = $stderr
331+
original_encoding = Encoding.default_external
332+
original_verbose = $VERBOSE
333+
334+
begin
335+
stderr_buffer = StringIO.new
336+
$stderr = stderr_buffer
337+
$VERBOSE = nil
338+
Encoding.default_external = Encoding::UTF_8
339+
$VERBOSE = original_verbose
340+
341+
completor = IRB::RegexpCompletor.new
342+
result = completor.completion_candidates('', 'b', '', bind: test_bind)
343+
344+
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))
345+
assert_not_include(result, nil)
346+
347+
stderr_buffer.truncate(0)
348+
stderr_buffer.rewind
349+
stderr_buffer = StringIO.new
350+
351+
completor.completion_candidates('', 'b', '', bind: test_bind)
352+
assert_empty(stderr_buffer.string)
353+
ensure
354+
$stderr = original_stderr
355+
Encoding.default_external = original_encoding
356+
$VERBOSE = original_verbose
357+
end
358+
end
359+
end
317360
end

0 commit comments

Comments
 (0)