Skip to content

Commit 6cd98c2

Browse files
YO4nobu
authored andcommitted
Allow IO#each_codepoint to work with unetc even when encoding conversion active
Using IO#each_codepoint together with IO#ungetc causes an unwanted exception when encoding conversion is active. C:\>ruby -e "open('NUL', 'rt') { |f| f.ungetc('aa'); f.each_codepoint { |c| p c }}" 97 -e:1:in 'IO#each_codepoint': byte oriented read for character buffered IO (IOError) from -e:1:in 'block in <main>' from -e:1:in 'Kernel#open' from -e:1:in '<main>' Fixes [Bug #21131]
1 parent 85bd3fb commit 6cd98c2

File tree

2 files changed

+19
-1
lines changed

2 files changed

+19
-1
lines changed

io.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4947,7 +4947,7 @@ rb_io_each_codepoint(VALUE io)
49474947
fptr->cbuf.off += n;
49484948
fptr->cbuf.len -= n;
49494949
rb_yield(UINT2NUM(c));
4950-
rb_io_check_byte_readable(fptr);
4950+
rb_io_check_char_readable(fptr);
49514951
}
49524952
}
49534953
NEED_NEWLINE_DECORATOR_ON_READ_CHECK(fptr);

test/ruby/test_io.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,24 @@ def test_each_codepoint_closed
467467
}
468468
end
469469

470+
def test_each_codepoint_with_ungetc
471+
bug21562 = '[ruby-core:123176] [Bug #21562]'
472+
with_read_pipe("") {|p|
473+
p.binmode
474+
p.ungetc("aa")
475+
a = ""
476+
p.each_codepoint { |c| a << c }
477+
assert_equal("aa", a, bug21562)
478+
}
479+
with_read_pipe("") {|p|
480+
p.set_encoding("ascii-8bit", universal_newline: true)
481+
p.ungetc("aa")
482+
a = ""
483+
p.each_codepoint { |c| a << c }
484+
assert_equal("aa", a, bug21562)
485+
}
486+
end
487+
470488
def test_rubydev33072
471489
t = make_tempfile
472490
path = t.path

0 commit comments

Comments
 (0)