Project

General

Profile

Actions

Bug #21686

open

In combination with IO#ungetbyte, the write position may become unpredictable.

Bug #21686: In combination with IO#ungetbyte, the write position may become unpredictable.

Added by YO4 (Yoshinao Muramatsu) about 20 hours ago. Updated about 6 hours ago.

Status:
Open
Assignee:
-
Target version:
-
ruby -v:
ruby 3.4.1 (2024-12-25 revision 48d4efcb85) +PRISM [x64-mingw-ucrt]
[ruby-core:123804]

Description

In the current implementation, using IO#ungetbyte can cause IO#pos to become negative.
Writing to the same file descriptor in this state will result in unexpected write positions.

require 'tempfile'

Tempfile.open do |f|
  f.write("0123456789")
  f.rewind
  f.getbyte        # rbuf filled
  f.ungetbyte("-") # f.pos => 0
  f.ungetbyte("-") # f.pos => -1
  f.write("x")     # seek to -1 failed in io_unread
  f.rewind
  p f.read         # => "0123456789x", wrote at the end, questionable
end

When internal io_unread() in io.c is called to prepare for a write operation while the actual file position is advancing due to reading,
lseek fails because it attempts to reset to a negative file position.

IO#seek has a similar issue.

Tempfile.open do |f|
  f.write("0123456789")
  f.rewind
  f.getbyte        # rbuf filled
  f.ungetbyte("-") # f.pos => 0
  f.ungetbyte("-") # f.pos => -1
  f.seek(0, File::SEEK_CUR)
  p f.pos          # => 10, this points to the last of rbuf.
end

I am preparing the PR, but I understand that there is discussion about the position where the write occurs and the possibility of the pos becoming negative.

Actions

Also available in: PDF Atom