Skip to content

Commit 0815317

Browse files
committed
Escape invalid byte sequence in Exception
This fixes #141.
1 parent e7bdcf6 commit 0815317

File tree

2 files changed

+33
-1
lines changed

2 files changed

+33
-1
lines changed

lib/irb.rb

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,29 @@ def eval_input
578578
end
579579
end
580580

581+
def convert_invalid_byte_sequence(str)
582+
str = str.force_encoding(Encoding::ASCII_8BIT)
583+
conv = Encoding::Converter.new(Encoding::ASCII_8BIT, Encoding::UTF_8)
584+
dst = String.new
585+
begin
586+
ret = conv.primitive_convert(str, dst)
587+
case ret
588+
when :invalid_byte_sequence
589+
conf.insert_output(conf.primitive_errinfo[3].dump[1..-2])
590+
redo
591+
when :undefined_conversion
592+
c = conv.primitive_errinfo[3].dup.force_encoding(conv.primitive_errinfo[1])
593+
conv.insert_output(c.dump[1..-2])
594+
redo
595+
when :incomplete_input
596+
conv.insert_output(conv.primitive_errinfo[3].dump[1..-2])
597+
when :finished
598+
end
599+
break
600+
end while nil
601+
dst
602+
end
603+
581604
def handle_exception(exc)
582605
if exc.backtrace && exc.backtrace[0] =~ /\/irb(2)?(\/.*|-.*|\.rb)?:/ && exc.class.to_s !~ /^IRB/ &&
583606
!(SyntaxError === exc) && !(EncodingError === exc)
@@ -621,7 +644,8 @@ def handle_exception(exc)
621644
end
622645
puts messages.reverse
623646
end
624-
m = exc.to_s.split(/\n/)
647+
converted_exc_s = convert_invalid_byte_sequence(exc.to_s.dup)
648+
m = converted_exc_s.split(/\n/)
625649
print "#{attr[1]}#{exc.class} (#{attr[4]}#{m.shift}#{attr[0, 1]})#{attr[]}\n"
626650
puts m.map {|s| "#{attr[1]}#{s}#{attr[]}\n"}
627651
if attr == ATTR_PLAIN

test/irb/test_raise_no_backtrace_exception.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,13 @@ def e.backtrace; nil; end
1313
raise e
1414
IRB
1515
end
16+
17+
def test_raise_exception_with_invalid_byte_sequence
18+
skip if RUBY_ENGINE == 'truffleruby'
19+
bundle_exec = ENV.key?('BUNDLE_GEMFILE') ? ['-rbundler/setup'] : []
20+
assert_in_out_err(bundle_exec + %w[-rirb -W0 -e IRB.start(__FILE__) -- -f --], <<~IRB, /StandardError \(A\\xF3B\)/, [])
21+
raise StandardError, "A\\xf3B"
22+
IRB
23+
end
1624
end
1725
end

0 commit comments

Comments
 (0)