From: "YO4 (Yoshinao Muramatsu) via ruby-core" Date: 2025-11-16T05:40:15+00:00 Subject: [ruby-core:123810] [Ruby Bug#21686] In combination with IO#ungetbyte, the write position may become unpredictable. Issue #21686 has been updated by YO4 (Yoshinao Muramatsu). As proposed in this issue, resolving this problem required determining a solution strategy across multiple methods with considering compatibility. While I'm only an external contributor and not a core team member, I'll boldly say that the patch appears to merely mask the problem. >From my perspective, that PR seemed likely to cause issues by resetting pointers while leaving the encoding converter's state untouched. However, I hesitated to speak up because I wanted to find the actual conditions where it would cause problems. As reviewers, they were required to be even more precise in their statements, and when solutions were unclear, they likely couldn't offer careless opinions. We still need to explore another solution, like javanthropus's proposals in Bug #20889. I hope my suggestion helps clarify the issues and move the case forward. ---------------------------------------- Bug #21686: In combination with IO#ungetbyte, the write position may become unpredictable. https://bugs.ruby-lang.org/issues/21686#change-115212 * Author: YO4 (Yoshinao Muramatsu) * Status: Open * ruby -v: ruby 3.4.1 (2024-12-25 revision 48d4efcb85) +PRISM [x64-mingw-ucrt] * Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- 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. ```ruby 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. ```ruby 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. -- https://bugs.ruby-lang.org/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/