summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNobuyoshi Nakada <[email protected]>2024-10-07 11:06:44 +0900
committerNobuyoshi Nakada <[email protected]>2024-10-07 11:06:44 +0900
commit773d140f65c1c8b726e107915bc003c186f38677 (patch)
treefd518d22df990ee1f91946830a7b4d5aad6744db
parentec526c61c937ea03c460c91b01552629d196695a (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.c18
-rw-r--r--test/ruby/test_io.rb8
2 files changed, 21 insertions, 5 deletions
diff --git a/io.c b/io.c
index b26f71056f..945c5f4fd1 100644
--- a/io.c
+++ b/io.c
@@ -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"