ruby-changes:49199
From: nobu <ko1@a...>
Date: Mon, 18 Dec 2017 13:32:59 +0900 (JST)
Subject: [ruby-changes:49199] nobu:r61317 (trunk): io.c: opening external command
nobu 2017-12-18 13:32:54 +0900 (Mon, 18 Dec 2017) New Revision: 61317 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=61317 Log: io.c: opening external command * io.c (rb_io_open_generic): when external command will be invoked as other than IO singleton method, probably unintentionally, warn if it is File or raise ArgumentError. From: Nobuyoshi Nakada <nobu@r...> Modified files: trunk/io.c trunk/test/ruby/test_io.rb Index: test/ruby/test_io.rb =================================================================== --- test/ruby/test_io.rb (revision 61316) +++ test/ruby/test_io.rb (revision 61317) @@ -2184,6 +2184,15 @@ class TestIO < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_io.rb#L2184 end end + def test_read_command + assert_warn(/invoke external command/) do + File.read("|#{EnvUtil.rubybin} -e puts") + end + assert_raise_with_message(ArgumentError, /invoke external command/) do + Class.new(IO).read("|#{EnvUtil.rubybin} -e puts") + end + end + def test_reopen make_tempfile {|t| open(__FILE__) do |f| Index: io.c =================================================================== --- io.c (revision 61316) +++ io.c (revision 61317) @@ -7069,10 +7069,10 @@ rb_f_open(int argc, VALUE *argv) https://github.com/ruby/ruby/blob/trunk/io.c#L7069 return rb_io_s_open(argc, argv, rb_cFile); } -static VALUE rb_io_open_generic(VALUE, int, int, const convconfig_t *, mode_t); +static VALUE rb_io_open_generic(VALUE, VALUE, int, int, const convconfig_t *, mode_t); static VALUE -rb_io_open(VALUE filename, VALUE vmode, VALUE vperm, VALUE opt) +rb_io_open(VALUE io, VALUE filename, VALUE vmode, VALUE vperm, VALUE opt) { int oflags, fmode; convconfig_t convconfig; @@ -7080,19 +7080,30 @@ rb_io_open(VALUE filename, VALUE vmode, https://github.com/ruby/ruby/blob/trunk/io.c#L7080 rb_io_extract_modeenc(&vmode, &vperm, opt, &oflags, &fmode, &convconfig); perm = NIL_P(vperm) ? 0666 : NUM2MODET(vperm); - return rb_io_open_generic(filename, oflags, fmode, &convconfig, perm); + return rb_io_open_generic(io, filename, oflags, fmode, &convconfig, perm); } static VALUE -rb_io_open_generic(VALUE filename, int oflags, int fmode, +rb_io_open_generic(VALUE klass, VALUE filename, int oflags, int fmode, const convconfig_t *convconfig, mode_t perm) { VALUE cmd; if (!NIL_P(cmd = check_pipe_command(filename))) { + if (klass != rb_cIO) { + ID func = rb_frame_this_func(); + VALUE fname = rb_id2str(func); + static const char MSG[] = "IO.%"PRIsVALUE" called on %"PRIsVALUE" to invoke external command"; + if (klass == rb_cFile) { + rb_warn(MSG, fname, klass); + } + else { + rb_raise(rb_eArgError, MSG, fname, klass); + } + } return pipe_open_s(cmd, rb_io_oflags_modestr(oflags), fmode, convconfig); } else { - return rb_file_open_generic(io_alloc(rb_cFile), filename, + return rb_file_open_generic(io_alloc(klass), filename, oflags, fmode, convconfig, perm); } } @@ -10155,7 +10166,7 @@ struct foreach_arg { https://github.com/ruby/ruby/blob/trunk/io.c#L10166 }; static void -open_key_args(int argc, VALUE *argv, VALUE opt, struct foreach_arg *arg) +open_key_args(VALUE klass, int argc, VALUE *argv, VALUE opt, struct foreach_arg *arg) { VALUE path, v; VALUE vmode = Qnil, vperm = Qnil; @@ -10178,7 +10189,7 @@ open_key_args(int argc, VALUE *argv, VAL https://github.com/ruby/ruby/blob/trunk/io.c#L10189 rb_check_arity(n, 0, 3); /* rb_io_open */ rb_scan_args(n, RARRAY_CONST_PTR(v), "02:", &vmode, &vperm, &opt); } - arg->io = rb_io_open(path, vmode, vperm, opt); + arg->io = rb_io_open(klass, path, vmode, vperm, opt); } static VALUE @@ -10232,7 +10243,7 @@ rb_io_s_foreach(int argc, VALUE *argv, V https://github.com/ruby/ruby/blob/trunk/io.c#L10243 argc = rb_scan_args(argc, argv, "13:", NULL, NULL, NULL, NULL, &opt); RETURN_ENUMERATOR(self, orig_argc, argv); extract_getline_args(argc-1, argv+1, &garg); - open_key_args(argc, argv, opt, &arg); + open_key_args(self, argc, argv, opt, &arg); if (NIL_P(arg.io)) return Qnil; extract_getline_opts(opt, &garg); check_getline_args(&garg.rs, &garg.limit, garg.io = arg.io); @@ -10284,7 +10295,7 @@ rb_io_s_readlines(int argc, VALUE *argv, https://github.com/ruby/ruby/blob/trunk/io.c#L10295 argc = rb_scan_args(argc, argv, "13:", NULL, NULL, NULL, NULL, &opt); extract_getline_args(argc-1, argv+1, &garg); - open_key_args(argc, argv, opt, &arg); + open_key_args(io, argc, argv, opt, &arg); if (NIL_P(arg.io)) return Qnil; extract_getline_opts(opt, &garg); check_getline_args(&garg.rs, &garg.limit, garg.io = arg.io); @@ -10360,7 +10371,7 @@ rb_io_s_read(int argc, VALUE *argv, VALU https://github.com/ruby/ruby/blob/trunk/io.c#L10371 struct foreach_arg arg; argc = rb_scan_args(argc, argv, "13:", NULL, NULL, &offset, NULL, &opt); - open_key_args(argc, argv, opt, &arg); + open_key_args(io, argc, argv, opt, &arg); if (NIL_P(arg.io)) return Qnil; if (!NIL_P(offset)) { struct seek_arg sarg; @@ -10409,7 +10420,7 @@ rb_io_s_binread(int argc, VALUE *argv, V https://github.com/ruby/ruby/blob/trunk/io.c#L10420 rb_scan_args(argc, argv, "12", NULL, NULL, &offset); FilePathValue(argv[0]); convconfig.enc = rb_ascii8bit_encoding(); - arg.io = rb_io_open_generic(argv[0], oflags, fmode, &convconfig, 0); + arg.io = rb_file_open_generic(io_alloc(io), argv[0], oflags, fmode, &convconfig, 0); if (NIL_P(arg.io)) return Qnil; arg.argv = argv+1; arg.argc = (argc > 1) ? 1 : 0; @@ -10435,7 +10446,7 @@ io_s_write0(struct write_arg *arg) https://github.com/ruby/ruby/blob/trunk/io.c#L10446 } static VALUE -io_s_write(int argc, VALUE *argv, int binary) +io_s_write(int argc, VALUE *argv, VALUE klass, int binary) { VALUE string, offset, opt; struct foreach_arg arg; @@ -10455,7 +10466,7 @@ io_s_write(int argc, VALUE *argv, int bi https://github.com/ruby/ruby/blob/trunk/io.c#L10466 if (NIL_P(offset)) mode |= O_TRUNC; rb_hash_aset(opt,sym_mode,INT2NUM(mode)); } - open_key_args(argc,argv,opt,&arg); + open_key_args(klass, argc, argv, opt, &arg); #ifndef O_BINARY if (binary) rb_io_binmode_m(arg.io); @@ -10529,7 +10540,7 @@ io_s_write(int argc, VALUE *argv, int bi https://github.com/ruby/ruby/blob/trunk/io.c#L10540 static VALUE rb_io_s_write(int argc, VALUE *argv, VALUE io) { - return io_s_write(argc, argv, 0); + return io_s_write(argc, argv, io, 0); } /* @@ -10544,7 +10555,7 @@ rb_io_s_write(int argc, VALUE *argv, VAL https://github.com/ruby/ruby/blob/trunk/io.c#L10555 static VALUE rb_io_s_binwrite(int argc, VALUE *argv, VALUE io) { - return io_s_write(argc, argv, 1); + return io_s_write(argc, argv, io, 1); } struct copy_stream_struct { -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/