aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Dalessio <mike.dalessio@gmail.com>2023-06-07 10:05:04 -0400
committerNobuyoshi Nakada <nobu@ruby-lang.org>2023-08-10 09:38:11 +0900
commitd2343368ab7e270118ea6baa9c6418bfed83135c (patch)
tree0e25287d42464b9812033f613234f3baa11c5517
parent984109b8363790723693ec04897b1155d899115f (diff)
downloadruby-d2343368ab7e270118ea6baa9c6418bfed83135c.tar.gz
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]
-rw-r--r--doc/command_injection.rdoc2
-rw-r--r--io.c153
-rw-r--r--spec/ruby/core/io/binread_spec.rb10
-rw-r--r--spec/ruby/core/io/foreach_spec.rb19
-rw-r--r--spec/ruby/core/io/read_spec.rb34
-rw-r--r--spec/ruby/core/io/readlines_spec.rb21
-rw-r--r--spec/ruby/core/io/write_spec.rb11
-rw-r--r--spec/ruby/core/kernel/open_spec.rb36
-rw-r--r--test/ruby/test_io.rb27
-rw-r--r--test/ruby/test_io_m17n.rb32
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:
diff --git a/io.c b/io.c
index 0eb8da3f4f..d0cc6f2d90 100644
--- a/io.c
+++ b/io.c
@@ -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