Bug #21672
open`IO::Buffer.new` does not check that flags are valid
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>
No data to display