You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
There are two moments when a BufRead object needs to empty it's internal
buffer:
- In a seek call;
- In a read call when all data in the internal buffer had been already
consumed and the output buffer has a greater or equal size than the
internal buffer.
In both cases, the buffer was not being properly emptied, but only
marked as consumed (self.pos = self.cap). That should be no problem if
the inner reader is only Read, but if it is Seek as well, then it's
possible to access the data in the buffer by using the seek_relative
method. In order to prevent this from happening, both self.pos and
self.cap should be set to 0.
Two test cases were added to detect that failure:
- test_buffered_reader_invalidated_after_read
- test_buffered_reader_invalidated_after_seek
Both tests are very similar to each other. The inner reader contains the
following data: [5, 6, 7, 0, 1, 2, 3, 4]. The buffer capacity is 3
bytes.
- First, we call fill_buffer, which loads [5, 6, 7] into the internal
buffer, and then consume those 3 bytes.
- Then we either read the 5 remaining bytes in a single read call or we
move to the end of the stream by calling seek. In both cases the
buffer should be emptied to prevent the previous data [5, 6, 7] from
being read.
- We now call seek_relative(-2) and read two bytes, which should give us
the last 2 bytes of the stream: [3, 4].
Before this commit, the the seek_relative method would consider that
we're still in the range of the internal buffer, so instead of fetching
data from the inner reader, it would return the two last bytes that were
incorrectly still in the buffer: [6, 7]. Therefore, the test would fail.
Now, when seek_relative is called the buffer is empty. So the expected
data [3, 4] is fetched from the inner reader and the test passes.
0 commit comments