* [ruby-core:121136] [Ruby master Bug#21151] IO and StringIO raise FrozenError even for read-only methods
@ 2025-02-20 22:42 headius (Charles Nutter) via ruby-core
2025-02-26 0:49 ` [ruby-core:121169] " shyouhei (Shyouhei Urabe) via ruby-core
2025-03-13 7:19 ` [ruby-core:121322] " matz (Yukihiro Matsumoto) via ruby-core
0 siblings, 2 replies; 3+ messages in thread
From: headius (Charles Nutter) via ruby-core @ 2025-02-20 22:42 UTC (permalink / raw)
To: ruby-core; +Cc: headius (Charles Nutter)
Issue #21151 has been reported by headius (Charles Nutter).
----------------------------------------
Bug #21151: IO and StringIO raise FrozenError even for read-only methods
https://bugs.ruby-lang.org/issues/21151
* Author: headius (Charles Nutter)
* Status: Open
* Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN
----------------------------------------
Problem
--------
While fixing a small [regression](https://github.com/ruby/stringio/issues/119) from my recent StringIO [fixes](https://github.com/ruby/stringio/issues/116) I discovered that a large number of read-only methods will fail if the StringIO is frozen. A few examples:
```
$ ruby -rstringio -e 's = StringIO.new; p s.lineno; s.freeze; p s.lineno'
0
-e:1:in 'StringIO#lineno': can't modify frozen StringIO: #<StringIO:0x0000000103711ea8> (FrozenError)
from -e:1:in '<main>'
$ ruby -rstringio -e 's = StringIO.new; p s.closed?; s.freeze; p s.closed?'
false
-e:1:in 'StringIO#closed?': can't modify frozen StringIO: #<StringIO:0x00000001008c1e68> (FrozenError)
from -e:1:in '<main>'
$ ruby -rstringio -e 's = StringIO.new; p s.eof?; s.freeze; p s.eof?'
true
-e:1:in 'StringIO#eof?': can't modify frozen StringIO: #<StringIO:0x000000011c171e80> (FrozenError)
from -e:1:in '<main>'
$ ruby -rstringio -e 's = StringIO.new; p s.pos; s.freeze; p s.pos'
0
-e:1:in 'StringIO#pos': can't modify frozen StringIO: #<StringIO:0x0000000105551df0> (FrozenError)
from -e:1:in '<main>'
```
@kou pointed out that IO also raises for at least `lineno` and suggested I re-open the issue here. I still believe these read-only operations should be allowed on frozen IO or StringIO.
Cause in StringIO
-----------------
This is because the `StringIO` macro calls `get_strio` which calls `rb_io_taint_check` which calls `rb_check_frozen`. The `StringIO` macro is used in almost every method to access the rb_stringio_t data structure.
A list of methods I believe should be operable when the StringIO is frozen (in stringio.c definition order):
* string (returns underlying String but does not mutate anything)
* lineno
* pos
* closed?/closed_read?/closed_write?
* eof/eof?
* sync
* pid (a dummy method but it writes nothing)
* fileno (dummy)
* pread (by definition does not modify state)
* isatty/tty?
* size/length
* external_encoding
* internal_encoding
In addition, `initialize_copy` probably should not require the original StringIO to be writable:
```
$ ruby -rstringio -e 's = StringIO.new("foo"); s.freeze; p s.dup'
-e:1:in 'StringIO#initialize_copy': can't modify frozen StringIO: #<StringIO:0x0000000102eb1df8> (FrozenError)
from -e:1:in 'Kernel#initialize_dup'
from -e:1:in 'Kernel#dup'
from -e:1:in '<main>'
```
The data from the original StringIO is unmodified by `initialize_copy`, other than the reference-counting `ptr->count` (which should not be subject to frozen checks).
Cause in IO
-----------
The `GetOpenFile` macro calls `RB_IO_POINTER` macro which calls `rb_io_taint_check` which calls `rb_check_frozen`.
Methods in IO that should work on a frozen IO include any of the above StringIO that currently raise. For example `lineno` uses `GetOpenFile`, but `fileno` does not and does not raise.
There's clearly some inconsistency here we can clean up.
Origin
------
I believe most of the StringIO cases are caused by this change from 2011 that added frozen checks to StringIO (the class and the macro): https://github.com/ruby/ruby/commit/d8d9bac5c8b071135e50ad3f21c8a9b6a9c06e54
In IO, this behavior dates way back to 2000 by @matz himself: https://github.com/ruby/ruby/commit/087c83d7ceed6893afff93066937fb570ae4a115
Notes
-----
I have started to fix the StringIO cases for JRuby in https://github.com/ruby/stringio/pull/122. I could probably fix the C version of StringIO as well, but I'm a little more unsure about how to fix IO.
--
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/
^ permalink raw reply [flat|nested] 3+ messages in thread
* [ruby-core:121169] [Ruby master Bug#21151] IO and StringIO raise FrozenError even for read-only methods
2025-02-20 22:42 [ruby-core:121136] [Ruby master Bug#21151] IO and StringIO raise FrozenError even for read-only methods headius (Charles Nutter) via ruby-core
@ 2025-02-26 0:49 ` shyouhei (Shyouhei Urabe) via ruby-core
2025-03-13 7:19 ` [ruby-core:121322] " matz (Yukihiro Matsumoto) via ruby-core
1 sibling, 0 replies; 3+ messages in thread
From: shyouhei (Shyouhei Urabe) via ruby-core @ 2025-02-26 0:49 UTC (permalink / raw)
To: ruby-core; +Cc: shyouhei (Shyouhei Urabe)
Issue #21151 has been updated by shyouhei (Shyouhei Urabe).
StringIO situation is different, but for an IO to be read it has to be writable; thus can not be frozen. See what OpenSSL people say aobut this: https://github.com/openssl/openssl/commit/b1d6e3f551ce7e081ed3e30d525253042ebb10a4
----------------------------------------
Bug #21151: IO and StringIO raise FrozenError even for read-only methods
https://bugs.ruby-lang.org/issues/21151#change-112108
* Author: headius (Charles Nutter)
* Status: Open
* Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN
----------------------------------------
Problem
--------
While fixing a small [regression](https://github.com/ruby/stringio/issues/119) from my recent StringIO [fixes](https://github.com/ruby/stringio/issues/116) I discovered that a large number of read-only methods will fail if the StringIO is frozen. A few examples:
```
$ ruby -rstringio -e 's = StringIO.new; p s.lineno; s.freeze; p s.lineno'
0
-e:1:in 'StringIO#lineno': can't modify frozen StringIO: #<StringIO:0x0000000103711ea8> (FrozenError)
from -e:1:in '<main>'
$ ruby -rstringio -e 's = StringIO.new; p s.closed?; s.freeze; p s.closed?'
false
-e:1:in 'StringIO#closed?': can't modify frozen StringIO: #<StringIO:0x00000001008c1e68> (FrozenError)
from -e:1:in '<main>'
$ ruby -rstringio -e 's = StringIO.new; p s.eof?; s.freeze; p s.eof?'
true
-e:1:in 'StringIO#eof?': can't modify frozen StringIO: #<StringIO:0x000000011c171e80> (FrozenError)
from -e:1:in '<main>'
$ ruby -rstringio -e 's = StringIO.new; p s.pos; s.freeze; p s.pos'
0
-e:1:in 'StringIO#pos': can't modify frozen StringIO: #<StringIO:0x0000000105551df0> (FrozenError)
from -e:1:in '<main>'
```
@kou pointed out that IO also raises for at least `lineno` and suggested I re-open the issue here. I still believe these read-only operations should be allowed on frozen IO or StringIO.
Cause in StringIO
-----------------
This is because the `StringIO` macro calls `get_strio` which calls `rb_io_taint_check` which calls `rb_check_frozen`. The `StringIO` macro is used in almost every method to access the rb_stringio_t data structure.
A list of methods I believe should be operable when the StringIO is frozen (in stringio.c definition order):
* string (returns underlying String but does not mutate anything)
* lineno
* pos
* closed?/closed_read?/closed_write?
* eof/eof?
* sync
* pid (a dummy method but it writes nothing)
* fileno (dummy)
* pread (by definition does not modify state)
* isatty/tty?
* size/length
* external_encoding
* internal_encoding
In addition, `initialize_copy` probably should not require the original StringIO to be writable:
```
$ ruby -rstringio -e 's = StringIO.new("foo"); s.freeze; p s.dup'
-e:1:in 'StringIO#initialize_copy': can't modify frozen StringIO: #<StringIO:0x0000000102eb1df8> (FrozenError)
from -e:1:in 'Kernel#initialize_dup'
from -e:1:in 'Kernel#dup'
from -e:1:in '<main>'
```
The data from the original StringIO is unmodified by `initialize_copy`, other than the reference-counting `ptr->count` (which should not be subject to frozen checks).
Cause in IO
-----------
The `GetOpenFile` macro calls `RB_IO_POINTER` macro which calls `rb_io_taint_check` which calls `rb_check_frozen`.
Methods in IO that should work on a frozen IO include those from the StringIO list above that currently raise. For example `lineno` uses `GetOpenFile` and raises, but `fileno` does not and does not raise.
There's clearly some inconsistency here we can clean up.
Origin
------
I believe most of the StringIO cases are caused by this change from 2011 that added frozen checks to StringIO (the class and the macro): https://github.com/ruby/ruby/commit/d8d9bac5c8b071135e50ad3f21c8a9b6a9c06e54
In IO, this behavior dates way back to 2000 by @matz himself: https://github.com/ruby/ruby/commit/087c83d7ceed6893afff93066937fb570ae4a115
Notes
-----
Originally filed as https://github.com/ruby/stringio/issues/120.
I have started to fix the StringIO cases for JRuby in https://github.com/ruby/stringio/pull/122. I could probably fix the C version of StringIO as well, but I'm a little more unsure about how to fix IO.
--
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/
^ permalink raw reply [flat|nested] 3+ messages in thread
* [ruby-core:121322] [Ruby master Bug#21151] IO and StringIO raise FrozenError even for read-only methods
2025-02-20 22:42 [ruby-core:121136] [Ruby master Bug#21151] IO and StringIO raise FrozenError even for read-only methods headius (Charles Nutter) via ruby-core
2025-02-26 0:49 ` [ruby-core:121169] " shyouhei (Shyouhei Urabe) via ruby-core
@ 2025-03-13 7:19 ` matz (Yukihiro Matsumoto) via ruby-core
1 sibling, 0 replies; 3+ messages in thread
From: matz (Yukihiro Matsumoto) via ruby-core @ 2025-03-13 7:19 UTC (permalink / raw)
To: ruby-core; +Cc: matz (Yukihiro Matsumoto)
Issue #21151 has been updated by matz (Yukihiro Matsumoto).
Status changed from Open to Feedback
First, I would like to know why you want to freeze `IO` and `StringIO`. I can't think of a use case.
If there is no valid reason, it would not help if all operations on a frozen `IO` were prohibited. If there could be a good reason, I would consider allowing the possible operations, as @headious said.
Matz.
----------------------------------------
Bug #21151: IO and StringIO raise FrozenError even for read-only methods
https://bugs.ruby-lang.org/issues/21151#change-112287
* Author: headius (Charles Nutter)
* Status: Feedback
* Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN
----------------------------------------
Problem
--------
While fixing a small [regression](https://github.com/ruby/stringio/issues/119) from my recent StringIO [fixes](https://github.com/ruby/stringio/issues/116) I discovered that a large number of read-only methods will fail if the StringIO is frozen. A few examples:
```
$ ruby -rstringio -e 's = StringIO.new; p s.lineno; s.freeze; p s.lineno'
0
-e:1:in 'StringIO#lineno': can't modify frozen StringIO: #<StringIO:0x0000000103711ea8> (FrozenError)
from -e:1:in '<main>'
$ ruby -rstringio -e 's = StringIO.new; p s.closed?; s.freeze; p s.closed?'
false
-e:1:in 'StringIO#closed?': can't modify frozen StringIO: #<StringIO:0x00000001008c1e68> (FrozenError)
from -e:1:in '<main>'
$ ruby -rstringio -e 's = StringIO.new; p s.eof?; s.freeze; p s.eof?'
true
-e:1:in 'StringIO#eof?': can't modify frozen StringIO: #<StringIO:0x000000011c171e80> (FrozenError)
from -e:1:in '<main>'
$ ruby -rstringio -e 's = StringIO.new; p s.pos; s.freeze; p s.pos'
0
-e:1:in 'StringIO#pos': can't modify frozen StringIO: #<StringIO:0x0000000105551df0> (FrozenError)
from -e:1:in '<main>'
```
@kou pointed out that IO also raises for at least `lineno` and suggested I re-open the issue here. I still believe these read-only operations should be allowed on frozen IO or StringIO.
Cause in StringIO
-----------------
This is because the `StringIO` macro calls `get_strio` which calls `rb_io_taint_check` which calls `rb_check_frozen`. The `StringIO` macro is used in almost every method to access the rb_stringio_t data structure.
A list of methods I believe should be operable when the StringIO is frozen (in stringio.c definition order):
* string (returns underlying String but does not mutate anything)
* lineno
* pos
* closed?/closed_read?/closed_write?
* eof/eof?
* sync
* pid (a dummy method but it writes nothing)
* fileno (dummy)
* pread (by definition does not modify state)
* isatty/tty?
* size/length
* external_encoding
* internal_encoding
In addition, `initialize_copy` probably should not require the original StringIO to be writable:
```
$ ruby -rstringio -e 's = StringIO.new("foo"); s.freeze; p s.dup'
-e:1:in 'StringIO#initialize_copy': can't modify frozen StringIO: #<StringIO:0x0000000102eb1df8> (FrozenError)
from -e:1:in 'Kernel#initialize_dup'
from -e:1:in 'Kernel#dup'
from -e:1:in '<main>'
```
The data from the original StringIO is unmodified by `initialize_copy`, other than the reference-counting `ptr->count` (which should not be subject to frozen checks).
Cause in IO
-----------
The `GetOpenFile` macro calls `RB_IO_POINTER` macro which calls `rb_io_taint_check` which calls `rb_check_frozen`.
Methods in IO that should work on a frozen IO include those from the StringIO list above that currently raise. For example `lineno` uses `GetOpenFile` and raises, but `fileno` does not and does not raise.
There's clearly some inconsistency here we can clean up.
Origin
------
I believe most of the StringIO cases are caused by this change from 2011 that added frozen checks to StringIO (the class and the macro): https://github.com/ruby/ruby/commit/d8d9bac5c8b071135e50ad3f21c8a9b6a9c06e54
In IO, this behavior dates way back to 2000 by @matz himself: https://github.com/ruby/ruby/commit/087c83d7ceed6893afff93066937fb570ae4a115
Notes
-----
Originally filed as https://github.com/ruby/stringio/issues/120.
I have started to fix the StringIO cases for JRuby in https://github.com/ruby/stringio/pull/122. I could probably fix the C version of StringIO as well, but I'm a little more unsure about how to fix IO.
--
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/
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2025-03-13 7:19 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-02-20 22:42 [ruby-core:121136] [Ruby master Bug#21151] IO and StringIO raise FrozenError even for read-only methods headius (Charles Nutter) via ruby-core
2025-02-26 0:49 ` [ruby-core:121169] " shyouhei (Shyouhei Urabe) via ruby-core
2025-03-13 7:19 ` [ruby-core:121322] " matz (Yukihiro Matsumoto) via ruby-core
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).