Bug #21672
Updated by trinistr (Alexander Bulancov) 8 days ago
`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` `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):~~ After further review this does seem to be valid: LOCKED): ``` IO::Buffer.map(File.open('README.md', 'r+'), nil, 0, 0xffffff) # #<IO::Buffer 0x00007fd8edb90000+9024 MAPPED FILE PRIVATE READONLY> ```