diff --git a/io.c b/io.c index c4b7f12..5997c29 100644 --- a/io.c +++ b/io.c @@ -457,6 +457,12 @@ io_unread(rb_io_t *fptr) /* add extra offset for removed '\r' in rbuf */ extra_max = (long)(pos - fptr->rbuf.len); p = fptr->rbuf.ptr + fptr->rbuf.off; + + /* if the end of rbuf is '\r', rbuf doesn't have '\r' within rbuf.len */ + if (*(fptr->rbuf.ptr + fptr->rbuf.capa - 1) == '\r') { + newlines++; + } + for (i = 0; i < fptr->rbuf.len; i++) { if (*p == '\n') newlines++; if (extra_max == newlines) break; diff --git a/test/ruby/test_io_m17n.rb b/test/ruby/test_io_m17n.rb index 719214d..b6358e0 100644 --- a/test/ruby/test_io_m17n.rb +++ b/test/ruby/test_io_m17n.rb @@ -2432,6 +2432,22 @@ EOT } end if /mswin|mingw/ =~ RUBY_PLATFORM + def test_pos_with_buffer_end_cr + bug6401 = '[ruby-core:44874]' + with_tmpdir { + # Read buffer size is 8191. This generates '\r' at 8191. + lines = ["X" * 8187, "X"] + generate_file("tmp", lines.join("\r\n") + "\r\n") + + open("tmp", "r") do |f| + lines.each do |line| + f.pos + assert_equal(line, f.readline.chomp, bug6401) + end + end + } + end if /mswin|mingw/ =~ RUBY_PLATFORM + def test_read_crlf_and_eof bug6271 = '[ruby-core:44189]' with_tmpdir {