File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -1470,7 +1470,11 @@ def tell(self):
14701470 def truncate (self , pos = None ):
14711471 if pos is None :
14721472 pos = self .tell ()
1473- # Use seek to flush the read buffer.
1473+ # Use seek to flush the read buffer and to rewind the raw stream, as
1474+ # _io's buffered_flush_and_rewind_unlocked() does. Without this a
1475+ # read after truncate() can still return data that was truncated
1476+ # away.
1477+ self .seek (self .tell ())
14741478 return BufferedWriter .truncate (self , pos )
14751479
14761480 def read (self , size = None ):
Original file line number Diff line number Diff line change @@ -1410,6 +1410,17 @@ def test_truncate_after_read_or_write(self):
14101410 self .assertEqual (bufio .write (b"BB" ), 2 ) # the write buffer increases
14111411 self .assertEqual (bufio .truncate (), 4 )
14121412
1413+ def test_read_after_truncate (self ):
1414+ # gh-161271: truncate() must drop the read-ahead buffer, so that a
1415+ # read after it cannot return data that is no longer in the stream.
1416+ raw = self .BytesIO (b"A" * 10 )
1417+ bufio = self .tp (raw , 100 )
1418+ self .assertEqual (bufio .read (2 ), b"AA" ) # the read buffer gets filled
1419+ self .assertEqual (bufio .truncate (0 ), 0 )
1420+ self .assertEqual (bufio .tell (), 2 )
1421+ self .assertEqual (bufio .read (), b"" )
1422+ self .assertEqual (raw .getvalue (), b"" )
1423+
14131424 def test_misbehaved_io (self ):
14141425 BufferedReaderTest .test_misbehaved_io (self )
14151426 BufferedWriterTest .test_misbehaved_io (self )
Original file line number Diff line number Diff line change 1+ Fix the pure Python implementation of :class: `io.BufferedRandom ` (``_pyio ``):
2+ :meth: `!truncate ` now drops the read-ahead buffer and rewinds the raw stream,
3+ as the C implementation does, so that a read after :meth: `!truncate ` no longer
4+ returns data that was truncated away.
You can’t perform that action at this time.
0 commit comments