aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoraycabta <aycabta@gmail.com>2021-05-09 12:12:42 +0900
committergit <svn-admin@ruby-lang.org>2021-05-11 09:32:08 +0900
commit774cc32b4d4962ef685fb852a2dbf1897f64a8f7 (patch)
treee350e6944f2bfe815b70c26ad96c8ea58c2d014c
parent4785d6087aa77a0ee28881ff9fb0737e8d5a97c5 (diff)
downloadruby-774cc32b4d4962ef685fb852a2dbf1897f64a8f7.tar.gz
[ruby/irb] Treat encodings in exception correctly
https://github.com/ruby/irb/commit/4452adbe04
-rw-r--r--lib/irb.rb15
-rw-r--r--test/irb/test_raise_no_backtrace_exception.rb25
2 files changed, 36 insertions, 4 deletions
diff --git a/lib/irb.rb b/lib/irb.rb
index 93c4d25c92..4b06f897da 100644
--- a/lib/irb.rb
+++ b/lib/irb.rb
@@ -590,9 +590,15 @@ module IRB
end
end
- def convert_invalid_byte_sequence(str)
- str = str.force_encoding(Encoding::ASCII_8BIT)
- conv = Encoding::Converter.new(Encoding::ASCII_8BIT, Encoding::UTF_8)
+ def convert_invalid_byte_sequence(str, enc)
+ str.force_encoding(enc)
+ str.scrub { |c|
+ c.bytes.map{ |b| "\\x#{b.to_s(16).upcase}" }.join
+ }
+ end
+
+ def encode_with_invalid_byte_sequence(str, enc)
+ conv = Encoding::Converter.new(str.encoding, enc)
dst = String.new
begin
ret = conv.primitive_convert(str, dst)
@@ -640,7 +646,8 @@ module IRB
message = exc.full_message(order: :top)
order = :top
end
- message = convert_invalid_byte_sequence(message)
+ message = convert_invalid_byte_sequence(message, exc.message.encoding)
+ message = encode_with_invalid_byte_sequence(message, IRB.conf[:LC_MESSAGES].encoding) if message.encoding != IRB.conf[:LC_MESSAGES].encoding
message = message.gsub(/((?:^\t.+$\n)+)/) { |m|
case order
when :top
diff --git a/test/irb/test_raise_no_backtrace_exception.rb b/test/irb/test_raise_no_backtrace_exception.rb
index 40ee0c52bf..925f39a81c 100644
--- a/test/irb/test_raise_no_backtrace_exception.rb
+++ b/test/irb/test_raise_no_backtrace_exception.rb
@@ -21,5 +21,30 @@ IRB
raise StandardError, "A\\xf3B"
IRB
end
+
+ def test_raise_exception_with_different_encoding_containing_invalid_byte_sequence
+ skip if RUBY_ENGINE == 'truffleruby'
+ backup_home = ENV["HOME"]
+ Dir.mktmpdir("test_irb_raise_no_backtrace_exception_#{$$}") do |tmpdir|
+ ENV["HOME"] = tmpdir
+
+ bundle_exec = ENV.key?('BUNDLE_GEMFILE') ? ['-rbundler/setup'] : []
+ File.open('euc.rb', 'w') do |f|
+ f.write(<<~EOF)
+ # encoding: euc-jp
+
+ def raise_euc_with_invalid_byte_sequence
+ raise "\xA4\xA2\\xFF"
+ end
+ EOF
+ end
+ assert_in_out_err(bundle_exec + %w[-rirb -W0 -e ENV[%(LC_ALL)]=%(ja_JP.UTF-8) -e ENV[%(LANG)]=%(ja_JP.UTF-8) -e IRB.start(__FILE__) -- -f --], <<~IRB, /`raise_euc_with_invalid_byte_sequence': あ\\xFF \(RuntimeError\)/, [])
+ require_relative 'euc'
+ raise_euc_with_invalid_byte_sequence
+ IRB
+ end
+ ensure
+ ENV["HOME"] = backup_home
+ end
end
end