ruby-changes:62325
From: Nobuyoshi <ko1@a...>
Date: Mon, 20 Jul 2020 14:59:40 +0900 (JST)
Subject: [ruby-changes:62325] 6ff9604f85 (master): [ruby/stringio] Raise an error if encoding conversion not succeeded
https://git.ruby-lang.org/ruby.git/commit/?id=6ff9604f85 From 6ff9604f85bf5ffcb6dbfd9ff99ab420c9a5f415 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada <nobu@r...> Date: Sat, 18 Jul 2020 23:52:27 +0900 Subject: [ruby/stringio] Raise an error if encoding conversion not succeeded As `rb_str_conv_enc()` returns the argument string object itself unchanged when any conversion failed, check the incompatibility in that case. Fixes https://github.com/ruby/stringio/issues/13 https://github.com/ruby/stringio/commit/ede6bdcc71 diff --git a/ext/stringio/stringio.c b/ext/stringio/stringio.c index b32a391..61a6b9a 100644 --- a/ext/stringio/stringio.c +++ b/ext/stringio/stringio.c @@ -1435,7 +1435,12 @@ strio_write(VALUE self, VALUE str) https://github.com/ruby/ruby/blob/trunk/ext/stringio/stringio.c#L1435 enc = get_enc(ptr); enc2 = rb_enc_get(str); if (enc != enc2 && enc != ascii8bit) { - str = rb_str_conv_enc(str, enc2, enc); + VALUE converted = rb_str_conv_enc(str, enc2, enc); + if (converted == str && enc2 != ascii8bit) { /* conversion failed */ + rb_enc_check(rb_enc_from_encoding(enc), str); + UNREACHABLE; + } + str = converted; } len = RSTRING_LEN(str); if (len == 0) return 0; diff --git a/test/stringio/test_stringio.rb b/test/stringio/test_stringio.rb index a99ccf4..3cf7f42 100644 --- a/test/stringio/test_stringio.rb +++ b/test/stringio/test_stringio.rb @@ -187,6 +187,31 @@ class TestStringIO < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/stringio/test_stringio.rb#L187 assert_equal(Encoding::UTF_8, s.encoding, "honor the original encoding over ASCII-8BIT") end + def test_write_encoding_conversion + convertible = "\u{3042}" + inconvertible = "\u{1f363}" + conversion_encoding = Encoding::Windows_31J + + s = StringIO.new.set_encoding(conversion_encoding) + s.write(convertible) + assert_equal(conversion_encoding, s.string.encoding) + all_assertions do |a| + [ + inconvertible, + convertible + inconvertible, + [convertible, inconvertible], + ["a", inconvertible], + ].each do |data| + a.for(data.inspect) do + s = StringIO.new.set_encoding(conversion_encoding) + assert_raise(Encoding::CompatibilityError) do + s.write(*data) + end + end + end + end + end + def test_write_integer_overflow f = StringIO.new f.pos = RbConfig::LIMITS["LONG_MAX"] -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/