Skip to content

Commit a6ec1ce

Browse files
ammaraskarberkerpeksag
authored andcommitted
bpo-33361: Fix bug with seeking in StreamRecoders (GH-8278)
1 parent aac4d03 commit a6ec1ce

File tree

3 files changed

+33
-0
lines changed

3 files changed

+33
-0
lines changed

Lib/codecs.py

+6
Original file line numberDiff line numberDiff line change
@@ -847,6 +847,12 @@ def reset(self):
847847
self.reader.reset()
848848
self.writer.reset()
849849

850+
def seek(self, offset, whence=0):
851+
# Seeks must be propagated to both the readers and writers
852+
# as they might need to reset their internal buffers.
853+
self.reader.seek(offset, whence)
854+
self.writer.seek(offset, whence)
855+
850856
def __getattr__(self, name,
851857
getattr=getattr):
852858

Lib/test/test_codecs.py

+25
Original file line numberDiff line numberDiff line change
@@ -3166,6 +3166,31 @@ def test_write(self):
31663166
sr.write(text.encode('latin1'))
31673167
self.assertEqual(bio.getvalue(), text.encode('utf-8'))
31683168

3169+
def test_seeking_read(self):
3170+
bio = io.BytesIO('line1\nline2\nline3\n'.encode('utf-16-le'))
3171+
sr = codecs.EncodedFile(bio, 'utf-8', 'utf-16-le')
3172+
3173+
self.assertEqual(sr.readline(), b'line1\n')
3174+
sr.seek(0)
3175+
self.assertEqual(sr.readline(), b'line1\n')
3176+
self.assertEqual(sr.readline(), b'line2\n')
3177+
self.assertEqual(sr.readline(), b'line3\n')
3178+
self.assertEqual(sr.readline(), b'')
3179+
3180+
def test_seeking_write(self):
3181+
bio = io.BytesIO('123456789\n'.encode('utf-16-le'))
3182+
sr = codecs.EncodedFile(bio, 'utf-8', 'utf-16-le')
3183+
3184+
# Test that seek() only resets its internal buffer when offset
3185+
# and whence are zero.
3186+
sr.seek(2)
3187+
sr.write(b'\nabc\n')
3188+
self.assertEqual(sr.readline(), b'789\n')
3189+
sr.seek(0)
3190+
self.assertEqual(sr.readline(), b'1\n')
3191+
self.assertEqual(sr.readline(), b'abc\n')
3192+
self.assertEqual(sr.readline(), b'789\n')
3193+
31693194

31703195
@unittest.skipIf(_testcapi is None, 'need _testcapi module')
31713196
class LocaleCodecTest(unittest.TestCase):
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix a bug in :class:`codecs.StreamRecoder` where seeking might leave old data in a
2+
buffer and break subsequent read calls. Patch by Ammar Askar.

0 commit comments

Comments
 (0)