[ruby/stringio] fix: prevent segfault in StringIO#seek with SEEK_END

on null device
(https://github.com/ruby/stringio/pull/137)

Fixes segmentation fault when calling `seek` with `SEEK_END` on null
device StringIO created by
  `StringIO.new(nil)`.

```bash
ruby -e "require 'stringio'; StringIO.new(nil).seek(0, IO::SEEK_END)"
```

I tested with below versions.

```bash
[koh@Kohs-MacBook-Pro] ~
% ruby -v;gem info stringio;sw_vers
ruby 3.4.5 (2025-07-16 revision 20cda200d3) +PRISM [arm64-darwin24]

*** LOCAL GEMS ***

stringio (3.1.2)
    Authors: Nobu Nakada, Charles Oliver Nutter
    Homepage: https://github.com/ruby/stringio
    Licenses: Ruby, BSD-2-Clause
    Installed at (default): /Users/koh/.local/share/mise/installs/ruby/3.4.5/lib/ruby/gems/3.4.0

    Pseudo IO on String
ProductName:            macOS
ProductVersion:         15.5
BuildVersion:           24F74
[koh@Kohs-MacBook-Pro] ~
%
```

9399747bf9
This commit is contained in:
koh-sh 2025-08-09 18:30:17 +09:00 committed by git
parent 60ca525fce
commit 23c0113932
2 changed files with 15 additions and 1 deletions

View file

@ -837,7 +837,11 @@ strio_seek(int argc, VALUE *argv, VALUE self)
offset = ptr->pos;
break;
case 2:
offset = RSTRING_LEN(ptr->string);
if (NIL_P(ptr->string)) {
offset = 0;
} else {
offset = RSTRING_LEN(ptr->string);
}
break;
default:
error_inval("invalid whence");

View file

@ -70,6 +70,16 @@ class TestStringIO < Test::Unit::TestCase
assert_nil io.getc
end
def test_seek_null
io = StringIO.new(nil)
assert_equal(0, io.seek(0, IO::SEEK_SET))
assert_equal(0, io.pos)
assert_equal(0, io.seek(0, IO::SEEK_CUR))
assert_equal(0, io.pos)
assert_equal(0, io.seek(0, IO::SEEK_END)) # This should not segfault
assert_equal(0, io.pos)
end
def test_truncate
io = StringIO.new("")
io.puts "abc"