diff options
author | Mike Dalessio <[email protected]> | 2023-06-07 10:05:04 -0400 |
---|---|---|
committer | Nobuyoshi Nakada <[email protected]> | 2023-08-10 09:38:11 +0900 |
commit | d2343368ab7e270118ea6baa9c6418bfed83135c (patch) | |
tree | 0e25287d42464b9812033f613234f3baa11c5517 | |
parent | 984109b8363790723693ec04897b1155d899115f (diff) |
Deprecate Kernel#open and IO support for subprocess creation/forking
Deprecate Kernel#open and IO support for subprocess creation and
forking. This deprecates subprocess creation and forking in
- Kernel#open
- URI.open
- IO.binread
- IO.foreach
- IO.readlines
- IO.read
- IO.write
This behavior is slated to be removed in Ruby 4.0
[Feature #19630]
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/7915
-rw-r--r-- | doc/command_injection.rdoc | 2 | ||||
-rw-r--r-- | io.c | 153 | ||||
-rw-r--r-- | spec/ruby/core/io/binread_spec.rb | 10 | ||||
-rw-r--r-- | spec/ruby/core/io/foreach_spec.rb | 19 | ||||
-rw-r--r-- | spec/ruby/core/io/read_spec.rb | 34 | ||||
-rw-r--r-- | spec/ruby/core/io/readlines_spec.rb | 21 | ||||
-rw-r--r-- | spec/ruby/core/io/write_spec.rb | 11 | ||||
-rw-r--r-- | spec/ruby/core/kernel/open_spec.rb | 36 | ||||
-rw-r--r-- | test/ruby/test_io.rb | 27 | ||||
-rw-r--r-- | test/ruby/test_io_m17n.rb | 32 |
10 files changed, 165 insertions, 180 deletions
diff --git a/doc/command_injection.rdoc b/doc/command_injection.rdoc index af09be23f0..4408b1839d 100644 --- a/doc/command_injection.rdoc +++ b/doc/command_injection.rdoc @@ -8,6 +8,7 @@ They should not be called with unknown or unsanitized commands. These methods include: - Kernel.system +- Kernel.open - {\`command` (backtick method)}[rdoc-ref:Kernel#`] (also called by the expression <tt>%x[command]</tt>). - IO.popen(command). @@ -17,6 +18,7 @@ These methods include: - IO.binwrite(command). - IO.readlines(command). - IO.foreach(command). +- URI.open(command). Note that some of these methods do not execute commands when called from subclass \File: @@ -8109,20 +8109,10 @@ check_pipe_command(VALUE filename_or_command) * open(path, mode = 'r', perm = 0666, **opts) -> io or nil * open(path, mode = 'r', perm = 0666, **opts) {|io| ... } -> obj * - * Creates an IO object connected to the given stream, file, or subprocess. + * Creates an IO object connected to the given file. * - * Required string argument +path+ determines which of the following occurs: - * - * - The file at the specified +path+ is opened. - * - The process forks. - * - A subprocess is created. - * - * Each of these is detailed below. - * - * <b>File Opened</b> - - * If +path+ does _not_ start with a pipe character (<tt>'|'</tt>), - * a file stream is opened with <tt>File.open(path, mode, perm, **opts)</tt>. + * This method has potential security vulnerabilities if called with untrusted input; + * see {Command Injection}[rdoc-ref:command_injection.rdoc]. * * With no block given, file stream is returned: * @@ -8139,67 +8129,6 @@ check_pipe_command(VALUE filename_or_command) * * See File.open for details. * - * <b>Process Forked</b> - * - * If +path+ is the 2-character string <tt>'|-'</tt>, the process forks - * and the child process is connected to the parent. - * - * With no block given: - * - * io = open('|-') - * if io - * $stderr.puts "In parent, child pid is #{io.pid}." - * else - * $stderr.puts "In child, pid is #{$$}." - * end - * - * Output: - * - * In parent, child pid is 27903. - * In child, pid is 27903. - * - * With a block given: - * - * open('|-') do |io| - * if io - * $stderr.puts "In parent, child pid is #{io.pid}." - * else - * $stderr.puts "In child, pid is #{$$}." - * end - * end - * - * Output: - * - * In parent, child pid is 28427. - * In child, pid is 28427. - * - * <b>Subprocess Created</b> - * - * If +path+ is <tt>'|command'</tt> (<tt>'command' != '-'</tt>), - * a new subprocess runs the command; its open stream is returned. - * Note that the command may be processed by shell if it contains - * shell metacharacters. - * - * With no block given: - * - * io = open('|echo "Hi!"') # => #<IO:fd 12> - * print io.gets - * io.close - * - * Output: - * - * "Hi!" - * - * With a block given, calls the block with the stream, then closes the stream: - * - * open('|echo "Hi!"') do |io| - * print io.gets - * end - * - * Output: - * - * "Hi!" - * */ static VALUE @@ -8222,6 +8151,8 @@ rb_f_open(int argc, VALUE *argv, VALUE _) else { VALUE cmd = check_pipe_command(tmp); if (!NIL_P(cmd)) { + // TODO: when removed in 4.0, update command_injection.rdoc + rb_warn_deprecated_to_remove_at(4.0, "Calling Kernel#open with a leading '|'", "IO.popen"); argv[0] = cmd; return rb_io_s_popen(argc, argv, rb_cIO); } @@ -8259,6 +8190,8 @@ rb_io_open_generic(VALUE klass, VALUE filename, int oflags, int fmode, { VALUE cmd; if (klass == rb_cIO && !NIL_P(cmd = check_pipe_command(filename))) { + // TODO: when removed in 4.0, update command_injection.rdoc + rb_warn_deprecated_to_remove_at(4.0, "IO process creation with a leading '|'", "IO.popen"); return pipe_open_s(cmd, rb_io_oflags_modestr(oflags), fmode, convconfig); } else { @@ -11914,9 +11847,6 @@ io_s_foreach(VALUE v) * IO.foreach(path, sep = $/, **opts) {|line| block } -> nil * IO.foreach(path, limit, **opts) {|line| block } -> nil * IO.foreach(path, sep, limit, **opts) {|line| block } -> nil - * IO.foreach(command, sep = $/, **opts) {|line| block } -> nil - * IO.foreach(command, limit, **opts) {|line| block } -> nil - * IO.foreach(command, sep, limit, **opts) {|line| block } -> nil * IO.foreach(...) -> an_enumerator * * Calls the block with each successive line read from the stream. @@ -11925,16 +11855,7 @@ io_s_foreach(VALUE v) * this method has potential security vulnerabilities if called with untrusted input; * see {Command Injection}[rdoc-ref:command_injection.rdoc]. * - * The first argument must be a string that is one of the following: - * - * - Path: if +self+ is a subclass of \IO (\File, for example), - * or if the string _does_ _not_ start with the pipe character (<tt>'|'</tt>), - * the string is the path to a file. - * - Command: if +self+ is the class \IO, - * and if the string starts with the pipe character, - * the rest of the string is a command to be executed as a subprocess. - * This usage has potential security vulnerabilities if called with untrusted input; - * see {Command Injection}[rdoc-ref:command_injection.rdoc]. + * The first argument must be a string that is the path to a file. * * With only argument +path+ given, parses lines from the file at the given +path+, * as determined by the default line separator, @@ -12028,9 +11949,6 @@ io_s_readlines(VALUE v) /* * call-seq: - * IO.readlines(command, sep = $/, **opts) -> array - * IO.readlines(command, limit, **opts) -> array - * IO.readlines(command, sep, limit, **opts) -> array * IO.readlines(path, sep = $/, **opts) -> array * IO.readlines(path, limit, **opts) -> array * IO.readlines(path, sep, limit, **opts) -> array @@ -12041,19 +11959,7 @@ io_s_readlines(VALUE v) * this method has potential security vulnerabilities if called with untrusted input; * see {Command Injection}[rdoc-ref:command_injection.rdoc]. * - * The first argument must be a string; - * its meaning depends on whether it starts with the pipe character (<tt>'|'</tt>): - * - * - If so (and if +self+ is \IO), - * the rest of the string is a command to be executed as a subprocess. - * - Otherwise, the string is the path to a file. - * - * With only argument +command+ given, executes the command in a shell, - * parses its $stdout into lines, as determined by the default line separator, - * and returns those lines in an array: - * - * IO.readlines('| cat t.txt') - * # => ["First line\n", "Second line\n", "\n", "Third line\n", "Fourth line\n"] + * The first argument must be a string that is the path to a file. * * With only argument +path+ given, parses lines from the file at the given +path+, * as determined by the default line separator, @@ -12062,8 +11968,6 @@ io_s_readlines(VALUE v) * IO.readlines('t.txt') * # => ["First line\n", "Second line\n", "\n", "Third line\n", "Fourth line\n"] * - * For both forms, command and path, the remaining arguments are the same. - * * With argument +sep+ given, parses lines as determined by that line separator * (see {Line Separator}[rdoc-ref:IO@Line+Separator]): * @@ -12136,7 +12040,6 @@ seek_before_access(VALUE argp) /* * call-seq: - * IO.read(command, length = nil, offset = 0, **opts) -> string or nil * IO.read(path, length = nil, offset = 0, **opts) -> string or nil * * Opens the stream, reads and returns some or all of its content, @@ -12146,18 +12049,7 @@ seek_before_access(VALUE argp) * this method has potential security vulnerabilities if called with untrusted input; * see {Command Injection}[rdoc-ref:command_injection.rdoc]. * - * The first argument must be a string; - * its meaning depends on whether it starts with the pipe character (<tt>'|'</tt>): - * - * - If so (and if +self+ is \IO), - * the rest of the string is a command to be executed as a subprocess. - * - Otherwise, the string is the path to a file. - * - * With only argument +command+ given, executes the command in a shell, - * returns its entire $stdout: - * - * IO.read('| cat t.txt') - * # => "First line\nSecond line\n\nThird line\nFourth line\n" + * The first argument must be a string that is the path to a file. * * With only argument +path+ given, reads in text mode and returns the entire content * of the file at the given path: @@ -12169,8 +12061,6 @@ seek_before_access(VALUE argp) * unread when encountering certain special bytes. Consider using * IO.binread if all bytes in the file should be read. * - * For both forms, command and path, the remaining arguments are the same. - * * With argument +length+, returns +length+ bytes if available: * * IO.read('t.txt', 7) # => "First l" @@ -12221,7 +12111,6 @@ rb_io_s_read(int argc, VALUE *argv, VALUE io) /* * call-seq: - * IO.binread(command, length = nil, offset = 0) -> string or nil * IO.binread(path, length = nil, offset = 0) -> string or nil * * Behaves like IO.read, except that the stream is opened in binary mode @@ -12326,7 +12215,6 @@ io_s_write(int argc, VALUE *argv, VALUE klass, int binary) /* * call-seq: - * IO.write(command, data, **opts) -> integer * IO.write(path, data, offset = 0, **opts) -> integer * * Opens the stream, writes the given +data+ to it, @@ -12336,25 +12224,9 @@ io_s_write(int argc, VALUE *argv, VALUE klass, int binary) * this method has potential security vulnerabilities if called with untrusted input; * see {Command Injection}[rdoc-ref:command_injection.rdoc]. * - * The first argument must be a string; - * its meaning depends on whether it starts with the pipe character (<tt>'|'</tt>): - * - * - If so (and if +self+ is \IO), - * the rest of the string is a command to be executed as a subprocess. - * - Otherwise, the string is the path to a file. - * - * With argument +command+ given, executes the command in a shell, - * passes +data+ through standard input, writes its output to $stdout, - * and returns the length of the given +data+: - * - * IO.write('| cat', 'Hello World!') # => 12 - * - * Output: - * - * Hello World! + * The first argument must be a string that is the path to a file. * - * With argument +path+ given, writes the given +data+ to the file - * at that path: + * With only argument +path+ given, writes the given +data+ to the file at that path: * * IO.write('t.tmp', 'abc') # => 3 * File.read('t.tmp') # => "abc" @@ -12393,7 +12265,6 @@ rb_io_s_write(int argc, VALUE *argv, VALUE io) /* * call-seq: - * IO.binwrite(command, string, offset = 0) -> integer * IO.binwrite(path, string, offset = 0) -> integer * * Behaves like IO.write, except that the stream is opened in binary mode diff --git a/spec/ruby/core/io/binread_spec.rb b/spec/ruby/core/io/binread_spec.rb index a3f752d8f9..418e89213b 100644 --- a/spec/ruby/core/io/binread_spec.rb +++ b/spec/ruby/core/io/binread_spec.rb @@ -44,4 +44,14 @@ describe "IO.binread" do it "raises an Errno::EINVAL when not passed a valid offset" do -> { IO.binread @fname, 0, -1 }.should raise_error(Errno::EINVAL) end + + ruby_version_is "3.3" do + # https://bugs.ruby-lang.org/issues/19630 + it "warns about deprecation given a path with a pipe" do + cmd = "|echo ok" + -> { + IO.binread(cmd) + }.should complain(/IO process creation with a leading '\|'/) + end + end end diff --git a/spec/ruby/core/io/foreach_spec.rb b/spec/ruby/core/io/foreach_spec.rb index c2276cf544..c361d27879 100644 --- a/spec/ruby/core/io/foreach_spec.rb +++ b/spec/ruby/core/io/foreach_spec.rb @@ -20,7 +20,10 @@ describe "IO.foreach" do platform_is :windows do cmd = "|cmd.exe /C echo hello&echo line2" end - IO.foreach(cmd) { |l| ScratchPad << l } + + suppress_warning do # https://bugs.ruby-lang.org/issues/19630 + IO.foreach(cmd) { |l| ScratchPad << l } + end ScratchPad.recorded.should == ["hello\n", "line2\n"] end @@ -28,7 +31,9 @@ describe "IO.foreach" do it "gets data from a fork when passed -" do parent_pid = $$ - IO.foreach("|-") { |l| ScratchPad << l } + suppress_warning do # https://bugs.ruby-lang.org/issues/19630 + IO.foreach("|-") { |l| ScratchPad << l } + end if $$ == parent_pid ScratchPad.recorded.should == ["hello\n", "from a fork\n"] @@ -39,6 +44,16 @@ describe "IO.foreach" do end end end + + ruby_version_is "3.3" do + # https://bugs.ruby-lang.org/issues/19630 + it "warns about deprecation given a path with a pipe" do + cmd = "|echo ok" + -> { + IO.foreach(cmd).to_a + }.should complain(/IO process creation with a leading '\|'/) + end + end end end diff --git a/spec/ruby/core/io/read_spec.rb b/spec/ruby/core/io/read_spec.rb index a829ffd18c..bd22fb6d6e 100644 --- a/spec/ruby/core/io/read_spec.rb +++ b/spec/ruby/core/io/read_spec.rb @@ -165,12 +165,19 @@ describe "IO.read from a pipe" do platform_is :windows do cmd = "|cmd.exe /C echo hello" end - IO.read(cmd).should == "hello\n" + + suppress_warning do # https://bugs.ruby-lang.org/issues/19630 + IO.read(cmd).should == "hello\n" + end end platform_is_not :windows do it "opens a pipe to a fork if the rest is -" do - str = IO.read("|-") + str = nil + suppress_warning do # https://bugs.ruby-lang.org/issues/19630 + str = IO.read("|-") + end + if str # parent str.should == "hello from child\n" else #child @@ -185,13 +192,18 @@ describe "IO.read from a pipe" do platform_is :windows do cmd = "|cmd.exe /C echo hello" end - IO.read(cmd, 1).should == "h" + + suppress_warning do # https://bugs.ruby-lang.org/issues/19630 + IO.read(cmd, 1).should == "h" + end end platform_is_not :windows do it "raises Errno::ESPIPE if passed an offset" do -> { - IO.read("|sh -c 'echo hello'", 1, 1) + suppress_warning do # https://bugs.ruby-lang.org/issues/19630 + IO.read("|sh -c 'echo hello'", 1, 1) + end }.should raise_error(Errno::ESPIPE) end end @@ -202,11 +214,23 @@ quarantine! do # The process tried to write to a nonexistent pipe. # once https://bugs.ruby-lang.org/issues/12230 is fixed. it "raises Errno::EINVAL if passed an offset" do -> { - IO.read("|cmd.exe /C echo hello", 1, 1) + suppress_warning do # https://bugs.ruby-lang.org/issues/19630 + IO.read("|cmd.exe /C echo hello", 1, 1) + end }.should raise_error(Errno::EINVAL) end end end + + ruby_version_is "3.3" do + # https://bugs.ruby-lang.org/issues/19630 + it "warns about deprecation given a path with a pipe" do + cmd = "|echo ok" + -> { + IO.read(cmd) + }.should complain(/IO process creation with a leading '\|'/) + end + end end describe "IO.read on an empty file" do diff --git a/spec/ruby/core/io/readlines_spec.rb b/spec/ruby/core/io/readlines_spec.rb index d6c4d539cf..3a6ff3d0f3 100644 --- a/spec/ruby/core/io/readlines_spec.rb +++ b/spec/ruby/core/io/readlines_spec.rb @@ -180,13 +180,20 @@ describe "IO.readlines" do platform_is :windows do cmd = "|cmd.exe /C echo hello&echo line2" end - lines = IO.readlines(cmd) + + lines = nil + suppress_warning do # https://bugs.ruby-lang.org/issues/19630 + lines = IO.readlines(cmd) + end lines.should == ["hello\n", "line2\n"] end platform_is_not :windows do it "gets data from a fork when passed -" do - lines = IO.readlines("|-") + lines = nil + suppress_warning do # https://bugs.ruby-lang.org/issues/19630 + lines = IO.readlines("|-") + end if lines # parent lines.should == ["hello\n", "from a fork\n"] @@ -199,6 +206,16 @@ describe "IO.readlines" do end end + ruby_version_is "3.3" do + # https://bugs.ruby-lang.org/issues/19630 + it "warns about deprecation given a path with a pipe" do + cmd = "|echo ok" + -> { + IO.readlines(cmd) + }.should complain(/IO process creation with a leading '\|'/) + end + end + it_behaves_like :io_readlines, :readlines it_behaves_like :io_readlines_options_19, :readlines end diff --git a/spec/ruby/core/io/write_spec.rb b/spec/ruby/core/io/write_spec.rb index 3f04fb053f..2e39b4fadd 100644 --- a/spec/ruby/core/io/write_spec.rb +++ b/spec/ruby/core/io/write_spec.rb @@ -215,6 +215,17 @@ describe "IO.write" do end end end + + ruby_version_is "3.3" do + # https://bugs.ruby-lang.org/issues/19630 + it "warns about deprecation given a path with a pipe" do + -> { + -> { + IO.write("|cat", "xxx") + }.should output_to_fd("xxx") + }.should complain(/IO process creation with a leading '\|'/) + end + end end end diff --git a/spec/ruby/core/kernel/open_spec.rb b/spec/ruby/core/kernel/open_spec.rb index 99793294c5..bb42c31f31 100644 --- a/spec/ruby/core/kernel/open_spec.rb +++ b/spec/ruby/core/kernel/open_spec.rb @@ -29,7 +29,9 @@ describe "Kernel#open" do platform_is_not :windows, :wasi do it "opens an io when path starts with a pipe" do - @io = open("|date") + suppress_warning do # https://bugs.ruby-lang.org/issues/19630 + @io = open("|date") + end begin @io.should be_kind_of(IO) @io.read @@ -39,21 +41,27 @@ describe "Kernel#open" do end it "opens an io when called with a block" do - @output = open("|date") { |f| f.read } + suppress_warning do # https://bugs.ruby-lang.org/issues/19630 + @output = open("|date") { |f| f.read } + end @output.should_not == '' end it "opens an io for writing" do - -> do - bytes = open("|cat", "w") { |io| io.write(".") } - bytes.should == 1 - end.should output_to_fd(".") + suppress_warning do # https://bugs.ruby-lang.org/issues/19630 + -> { + bytes = open("|cat", "w") { |io| io.write(".") } + bytes.should == 1 + }.should output_to_fd(".") + end end end platform_is :windows do it "opens an io when path starts with a pipe" do - @io = open("|date /t") + suppress_warning do # https://bugs.ruby-lang.org/issues/19630 + @io = open("|date /t") + end begin @io.should be_kind_of(IO) @io.read @@ -63,11 +71,23 @@ describe "Kernel#open" do end it "opens an io when called with a block" do - @output = open("|date /t") { |f| f.read } + suppress_warning do # https://bugs.ruby-lang.org/issues/19630 + @output = open("|date /t") { |f| f.read } + end @output.should_not == '' end end + ruby_version_is "3.3" do + # https://bugs.ruby-lang.org/issues/19630 + it "warns about deprecation given a path with a pipe" do + cmd = "|echo ok" + -> { + open(cmd) { |f| f.read } + }.should complain(/Kernel#open with a leading '\|'/) + end + end + it "raises an ArgumentError if not passed one argument" do -> { open }.should raise_error(ArgumentError) end diff --git a/test/ruby/test_io.rb b/test/ruby/test_io.rb index aad1530588..7689b52e23 100644 --- a/test/ruby/test_io.rb +++ b/test/ruby/test_io.rb @@ -2412,15 +2412,19 @@ class TestIO < Test::Unit::TestCase end def test_open_pipe - open("|" + EnvUtil.rubybin, "r+") do |f| - f.puts "puts 'foo'" - f.close_write - assert_equal("foo\n", f.read) + assert_deprecated_warning(/Kernel#open with a leading '\|'/) do # https://bugs.ruby-lang.org/issues/19630 + open("|" + EnvUtil.rubybin, "r+") do |f| + f.puts "puts 'foo'" + f.close_write + assert_equal("foo\n", f.read) + end end end def test_read_command - assert_equal("foo\n", IO.read("|echo foo")) + assert_deprecated_warning(/IO process creation with a leading '\|'/) do # https://bugs.ruby-lang.org/issues/19630 + assert_equal("foo\n", IO.read("|echo foo")) + end assert_raise(Errno::ENOENT, Errno::EINVAL) do File.read("|#{EnvUtil.rubybin} -e puts") end @@ -2434,7 +2438,9 @@ class TestIO < Test::Unit::TestCase Class.new(IO).binread("|#{EnvUtil.rubybin} -e puts") end assert_raise(Errno::ESPIPE) do - IO.read("|echo foo", 1, 1) + assert_deprecated_warning(/IO process creation with a leading '\|'/) do # https://bugs.ruby-lang.org/issues/19630 + IO.read("|echo foo", 1, 1) + end end end @@ -2619,11 +2625,16 @@ class TestIO < Test::Unit::TestCase def test_foreach a = [] - IO.foreach("|" + EnvUtil.rubybin + " -e 'puts :foo; puts :bar; puts :baz'") {|x| a << x } + + assert_deprecated_warning(/IO process creation with a leading '\|'/) do # https://bugs.ruby-lang.org/issues/19630 + IO.foreach("|" + EnvUtil.rubybin + " -e 'puts :foo; puts :bar; puts :baz'") {|x| a << x } + end assert_equal(["foo\n", "bar\n", "baz\n"], a) a = [] - IO.foreach("|" + EnvUtil.rubybin + " -e 'puts :zot'", :open_args => ["r"]) {|x| a << x } + assert_deprecated_warning(/IO process creation with a leading '\|'/) do # https://bugs.ruby-lang.org/issues/19630 + IO.foreach("|" + EnvUtil.rubybin + " -e 'puts :zot'", :open_args => ["r"]) {|x| a << x } + end assert_equal(["zot\n"], a) make_tempfile {|t| diff --git a/test/ruby/test_io_m17n.rb b/test/ruby/test_io_m17n.rb index 267975d4ac..b01d627d92 100644 --- a/test/ruby/test_io_m17n.rb +++ b/test/ruby/test_io_m17n.rb @@ -1396,23 +1396,27 @@ EOT end def test_open_pipe_r_enc - open("|#{EnvUtil.rubybin} -e 'putc 255'", "r:ascii-8bit") {|f| - assert_equal(Encoding::ASCII_8BIT, f.external_encoding) - assert_equal(nil, f.internal_encoding) - s = f.read - assert_equal(Encoding::ASCII_8BIT, s.encoding) - assert_equal("\xff".force_encoding("ascii-8bit"), s) - } + EnvUtil.suppress_warning do # https://bugs.ruby-lang.org/issues/19630 + open("|#{EnvUtil.rubybin} -e 'putc 255'", "r:ascii-8bit") {|f| + assert_equal(Encoding::ASCII_8BIT, f.external_encoding) + assert_equal(nil, f.internal_encoding) + s = f.read + assert_equal(Encoding::ASCII_8BIT, s.encoding) + assert_equal("\xff".force_encoding("ascii-8bit"), s) + } + end end def test_open_pipe_r_enc2 - open("|#{EnvUtil.rubybin} -e 'putc \"\\u3042\"'", "r:UTF-8") {|f| - assert_equal(Encoding::UTF_8, f.external_encoding) - assert_equal(nil, f.internal_encoding) - s = f.read - assert_equal(Encoding::UTF_8, s.encoding) - assert_equal("\u3042", s) - } + EnvUtil.suppress_warning do # https://bugs.ruby-lang.org/issues/19630 + open("|#{EnvUtil.rubybin} -e 'putc \"\\u3042\"'", "r:UTF-8") {|f| + assert_equal(Encoding::UTF_8, f.external_encoding) + assert_equal(nil, f.internal_encoding) + s = f.read + assert_equal(Encoding::UTF_8, s.encoding) + assert_equal("\u3042", s) + } + end end def test_s_foreach_enc |