diff options
author | Nobuyoshi Nakada <[email protected]> | 2024-10-07 11:06:44 +0900 |
---|---|---|
committer | Nobuyoshi Nakada <[email protected]> | 2024-10-07 11:06:44 +0900 |
commit | 773d140f65c1c8b726e107915bc003c186f38677 (patch) | |
tree | fd518d22df990ee1f91946830a7b4d5aad6744db | |
parent | ec526c61c937ea03c460c91b01552629d196695a (diff) |
[Bug #20787] Check the separator in `IO#readline` as well as 3.2
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/11811
-rw-r--r-- | io.c | 18 | ||||
-rw-r--r-- | test/ruby/test_io.rb | 8 |
2 files changed, 21 insertions, 5 deletions
@@ -4396,23 +4396,31 @@ rb_io_set_lineno(VALUE io, VALUE lineno) static VALUE io_readline(rb_execution_context_t *ec, VALUE io, VALUE sep, VALUE lim, VALUE chomp) { + long limit = -1; if (NIL_P(lim)) { + VALUE tmp = Qnil; // If sep is specified, but it's not a string and not nil, then assume // it's the limit (it should be an integer) - if (!NIL_P(sep) && NIL_P(rb_check_string_type(sep))) { + if (!NIL_P(sep) && NIL_P(tmp = rb_check_string_type(sep))) { // If the user has specified a non-nil / non-string value // for the separator, we assume it's the limit and set the // separator to default: rb_rs. lim = sep; + limit = NUM2LONG(lim); sep = rb_rs; } + else { + sep = tmp; + } } - - if (!NIL_P(sep)) { - StringValue(sep); + else { + if (!NIL_P(sep)) StringValue(sep); + limit = NUM2LONG(lim); } - VALUE line = rb_io_getline_1(sep, NIL_P(lim) ? -1L : NUM2LONG(lim), RTEST(chomp), io); + check_getline_args(&sep, &limit, io); + + VALUE line = rb_io_getline_1(sep, limit, RTEST(chomp), io); rb_lastline_set_up(line, 1); if (NIL_P(line)) { diff --git a/test/ruby/test_io.rb b/test/ruby/test_io.rb index 1ca05ae362..a623fd1d15 100644 --- a/test/ruby/test_io.rb +++ b/test/ruby/test_io.rb @@ -2002,6 +2002,14 @@ class TestIO < Test::Unit::TestCase end end + def test_readline_incompatible_rs + first_line = File.open(__FILE__, &:gets).encode("utf-32le") + File.open(__FILE__, encoding: "utf-8:utf-32le") {|f| + assert_equal first_line, f.readline + assert_raise(ArgumentError) {f.readline("\0")} + } + end + def test_set_lineno_readline pipe(proc do |w| w.puts "foo" |