Project

General

Profile

Actions

Bug #21672

open

`IO::Buffer.new` does not check that flags are valid

Bug #21672: `IO::Buffer.new` does not check that flags are valid

Added by trinistr (Alexander Bulancov) 5 days ago. Updated 1 day ago.

Status:
Assigned
Target version:
-
ruby -v:
ruby 3.4.7 (2025-10-08 revision 7a5688e2a2) +PRISM [x86_64-linux]
[ruby-core:123724]

Description

IO::Buffer.new has a flags argument that allows to override automatic decision between INTERNAL and MAPPED. As far as I understand, these modes are supposed to be exclusive, however in practice there is no check, and the user is free to specify both:

IO::Buffer.new(10, IO::Buffer::MAPPED|IO::Buffer::INTERNAL)
# => 
# #<IO::Buffer 0x0000555bfdccf760+10 INTERNAL MAPPED>
# 0x00000000  00 00 00 00 00 00 00 00 00 00                   ..........

From the source code in https://github.com/ruby/ruby/blob/master/io_buffer.c#L204, the real mode seems to be INTERNAL. I imagine that the order of branches can be reversed with changes, suddenly changing behavior.

Even worse, if at least one of INTERNAL or MAPPED is specified, flags are not checked at all, allowing complete nonsense:

IO::Buffer.new(10, 0xffffff)
# #<IO::Buffer 0x000055672a653190+10 EXTERNAL INTERNAL MAPPED SHARED LOCKED PRIVATE READONLY>

IO::Buffer.map also exhibits this issue, though I'm unsure if this combination of flags is actually invalid (it at least doesn't get LOCKED):

IO::Buffer.map(File.open('README.md', 'r+'), nil, 0, 0xffffff) 
# #<IO::Buffer 0x00007fd8edb90000+9024 MAPPED FILE PRIVATE READONLY>

Updated by trinistr (Alexander Bulancov) 5 days ago Actions #1 [ruby-core:123733]

Also not sure if this is intentional, but a buffer mapped from a file with IO::Buffer::PRIVATE is neither internal nor external:

IO::Buffer.map(File.open("README.md", "r+"), nil, 0, IO::Buffer::PRIVATE).external?
# => false
IO::Buffer.map(File.open("README.md", "r+"), nil, 0, IO::Buffer::PRIVATE).internal?
# => false

Updated by mame (Yusuke Endoh) 2 days ago Actions #2 [ruby-core:123760]

  • Status changed from Open to Assigned
  • Assignee set to ioquatix (Samuel Williams)

Updated by ioquatix (Samuel Williams) 2 days ago Actions #3 [ruby-core:123761]

Thanks, I'll review. IIRC, the flags provided can be advisory, e.g. a small buffer but use mapped memory.

Updated by trinistr (Alexander Bulancov) 1 day ago Actions #4 [ruby-core:123771]

Thank you!

For more context: I'm working on IO::Buffer's specs for ruby/spec. This issue was created quite early, as I started with .new, and since then I've discovered a whole bunch of questionable or unclear behaviors (or just plain outdated documentation). I've been compiling a list in the PR here: https://github.com/ruby/spec/pull/1297. What's the usual process for dealing with a sizable list of maybe-issues? Creating separate issues for everything here seems like an overkill. I can make PRs for most of that stuff, I think, but it's hard to know what's actually intended sometimes.

Updated by headius (Charles Nutter) 1 day ago Actions #5 [ruby-core:123772]

@trinistr First off, Thanks for your work on specs recently. I did a quick implementation of IO::Buffer for j Ruby last year but only relied on the core tests. Having a complete set of specs will be very helpful.

Along with these flags, I want to point out that there's likely platform specific behaviors in this class that will need special treatment in tests and specs. Some of the features can't be supported outside of CRuby's runtime, some of them will be specific to unix's or even specific types of unix, etc.

The JRuby implementation ships with all recent builds of JRuby 10, so it would be worth comparing the specs with our version of behavior as well (and of course I'll have to pass those specs at some point anyway).

Feel free to contact me directly at or on the JRuby Matrix chat room if you have questions or want to work together on this.

Actions

Also available in: PDF Atom