diff options
author | koh-sh <34917718+koh-sh@users.noreply.github.com> | 2025-08-09 18:30:17 +0900 |
---|---|---|
committer | git <svn-admin@ruby-lang.org> | 2025-08-09 09:30:27 +0000 |
commit | 23c0113932407abccddbc6ee5b297d38d2d2bb9c (patch) | |
tree | 2c3f47e000b9f6dd4706e0fe3a8aa00ae71f64c6 | |
parent | 60ca525fce71b702ea8e5893c976044170a56d75 (diff) |
[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 https://github.com/ruby/stringio/commit/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] ~
%
```
https://github.com/ruby/stringio/commit/9399747bf9
-rw-r--r-- | ext/stringio/stringio.c | 6 | ||||
-rw-r--r-- | test/stringio/test_stringio.rb | 10 |
2 files changed, 15 insertions, 1 deletions
diff --git a/ext/stringio/stringio.c b/ext/stringio/stringio.c index 3003939e10..d9beb25434 100644 --- a/ext/stringio/stringio.c +++ b/ext/stringio/stringio.c @@ -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"); diff --git a/test/stringio/test_stringio.rb b/test/stringio/test_stringio.rb index 002b946b6f..4c9cf37425 100644 --- a/test/stringio/test_stringio.rb +++ b/test/stringio/test_stringio.rb @@ -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" |