-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
A seek on a closed channel can allow invalid input
s
#11878
Comments
Interesting example, thanks! I'm surprised that "the extra byte(s) we input were never really read from the file". Seeking can move within data already read in the buffer, but should not expose parts of the buffer that have not been read. Maybe this is the root of the problem, independently of whether the channel is closed between the two |
Here is, step by step, my understanding of what happens in that example. Lines 171 to 174 in d70eae0
Then we seek to position 1 with caml_seek_in , offset is 1, curr and max are assigned again at the beginning of the buffer.Lines 437 to 443 in d70eae0
Then we close the channel with caml_ml_close_channel , curr and max are set to the end of the buffer but, critically, offset is not modified (so keep at 1).Lines 680 to 683 in d70eae0
Then we seek back with caml_seek_in , but this time the condition is true, the function assumes that we are seeking inside data in the buffer (note though that no read ever happened), so curr points now to the last byte of the buffer.Lines 431 to 434 in d70eae0
Then the next input will read that byte, because it is deemed valid. |
Thanks for the step-by-step. It's now clear in my mind that the problem is with |
Add a test demonstrating issue ocaml#11878
If offset keeps its value when the channel is closed, it is possible to `seek_in` backward which will only decrease `channel->curr` and therefore mark some buffer bytes as valid: further calls to `input_byte` would succeed on the closed channel Fix issue ocaml#11878
Add a test demonstrating issue ocaml#11878
If offset keeps its value when the channel is closed, it is possible to `seek_in` backward which will only decrease `channel->curr` and therefore mark some buffer bytes as valid: further calls to `input_byte` would succeed on the closed channel Fix issue ocaml#11878
Add a test demonstrating issue ocaml#11878
If offset keeps its value when the channel is closed, it is possible to `seek_in` backward which will only decrease `channel->curr` and therefore mark some buffer bytes as valid: further calls to `input_byte` would succeed on the closed channel Fix issue ocaml#11878
This reverts a technical decision made in ocaml#11878, ocaml#11965, for the purpose of simplifying the implementation of [close_in] and the specification of [seek_in], which now consistently fails on closed channels.
… channel (ocaml#11965) * Test calls to input_byte after close_in Add a test demonstrating issue ocaml#11878 * Reset offset when closing a channel If offset keeps its value when the channel is closed, it is possible to `seek_in` backward which will only decrease `channel->curr` and therefore mark some buffer bytes as valid: further calls to `input_byte` would succeed on the closed channel Fixes: ocaml#11878 (cherry picked from commit a606e92)
While running some qcheck-lin tests of
In_channel
, I ran into a problem which boils down to this test:yielding:
Replacing the first
seek_in
byseek_in f 10
would allow inputting 10 bytes before getting an exception.In this example, the extra byte(s) we input were never really read from the file, they are what’s currently in the buffer (which is not initialized, I think, which would explain that random testing it could find such a code giving non-deterministic results).
As I understand
caml_ml_close_channel
, we want to avoid testing explicitly whether the channel is indeed open in every function and rather rely on failing syscalls to detect it. So I checked that simply resetting the offset when closing the file:is enough to get an exception on the first
input
after closing. It does still allow for theseek_in
on the closed channel, so that’s maybe not the best way to go.The text was updated successfully, but these errors were encountered: