From cee29cb8fbbaadcac6c04172c1b4a4ece1a4b32b Mon Sep 17 00:00:00 2001 From: ksaito Date: Thu, 29 May 2025 23:06:35 +0900 Subject: [PATCH 1/2] Add validation for Encoding.default_external --- lib/reline/config.rb | 7 +++++++ test/reline/test_config.rb | 30 ++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/lib/reline/config.rb b/lib/reline/config.rb index e0fc37fc68..bfa2942bc6 100644 --- a/lib/reline/config.rb +++ b/lib/reline/config.rb @@ -177,6 +177,13 @@ def read_lines(lines, file = nil) if_stack = [] lines.each_with_index do |line, no| + # Even after encoding conversion, we need to verify the encoding is valid + # as some invalid byte sequences might pass through the conversion. + unless line.valid_encoding? + mes = "Warning invalid byte sequence found at line #{no + 1} in inputrc file#{file ? " (#{file})" : ""}. can't be converted to the locale #{Encoding.default_external}." + warn mes + next + end next if line.match(/\A\s*#/) no += 1 diff --git a/test/reline/test_config.rb b/test/reline/test_config.rb index 3c9094eece..f2156cd876 100644 --- a/test/reline/test_config.rb +++ b/test/reline/test_config.rb @@ -613,4 +613,34 @@ def test_reload @config.reload assert_equal '@', @config.emacs_mode_string end + + def test_warning_for_invalid_byte_sequence_with_utf8 + inputrc = "#{@tmpdir}/inputrc" + ENV['INPUTRC'] = inputrc + + File.open(inputrc, "w") do |f| + f.puts("# This is a comment") + f.write("set vi-cmd-mode-string ") + f.write([0xFF].pack("C*")) # Invalid UTF-8 byte sequence + f.puts("") + end + + def capture_stderr + original_stderr = $stderr + $stderr = StringIO.new + yield + $stderr.string + ensure + $stderr = original_stderr + end + + output = capture_stderr do + @config.read + end + + assert_match(/Warning invalid byte sequence found at line 2 in inputrc file/, output) + assert_match(/can't be converted to the locale/, output) + rescue Encoding::InvalidByteSequenceError + # do nothing + end end From debc1030e763e65211ccca19850f1868c2c398b2 Mon Sep 17 00:00:00 2001 From: ksaito Date: Sun, 22 Jun 2025 12:55:16 +0900 Subject: [PATCH 2/2] Fix raise InvalidInputrc exception for invalid byte sequences --- lib/reline/config.rb | 4 +--- test/reline/test_config.rb | 37 ++++++++++++------------------------- 2 files changed, 13 insertions(+), 28 deletions(-) diff --git a/lib/reline/config.rb b/lib/reline/config.rb index bfa2942bc6..d437156650 100644 --- a/lib/reline/config.rb +++ b/lib/reline/config.rb @@ -180,9 +180,7 @@ def read_lines(lines, file = nil) # Even after encoding conversion, we need to verify the encoding is valid # as some invalid byte sequences might pass through the conversion. unless line.valid_encoding? - mes = "Warning invalid byte sequence found at line #{no + 1} in inputrc file#{file ? " (#{file})" : ""}. can't be converted to the locale #{Encoding.default_external}." - warn mes - next + raise InvalidInputrc, "#{file}:#{no + 1}: can't be converted to the locale #{Reline.encoding_system_needs.name}" end next if line.match(/\A\s*#/) diff --git a/test/reline/test_config.rb b/test/reline/test_config.rb index f2156cd876..ff3e121ab0 100644 --- a/test/reline/test_config.rb +++ b/test/reline/test_config.rb @@ -614,33 +614,20 @@ def test_reload assert_equal '@', @config.emacs_mode_string end - def test_warning_for_invalid_byte_sequence_with_utf8 - inputrc = "#{@tmpdir}/inputrc" - ENV['INPUTRC'] = inputrc + def test_invalid_byte_sequence_inputrc + lines = [ + "set vi-cmd-mode-string\n", + "$if Ruby\n", + " \"\C-a\": \"Ruby\"\n", + "$else \"\xFF\"\n".dup.force_encoding(Reline.encoding_system_needs), # Invalid byte sequence + " \"\C-b\": \"NotRuby\"\n", + "$endif\n" + ] - File.open(inputrc, "w") do |f| - f.puts("# This is a comment") - f.write("set vi-cmd-mode-string ") - f.write([0xFF].pack("C*")) # Invalid UTF-8 byte sequence - f.puts("") - end - - def capture_stderr - original_stderr = $stderr - $stderr = StringIO.new - yield - $stderr.string - ensure - $stderr = original_stderr - end - - output = capture_stderr do - @config.read + e = assert_raise(Reline::Config::InvalidInputrc) do + @config.read_lines(lines, "INPUTRC") end - assert_match(/Warning invalid byte sequence found at line 2 in inputrc file/, output) - assert_match(/can't be converted to the locale/, output) - rescue Encoding::InvalidByteSequenceError - # do nothing + assert_equal "INPUTRC:4: can't be converted to the locale #{Reline.encoding_system_needs}", e.message end end