bpo-38334: Fix seeking backward on an encrypted zipfile.ZipExtFile. (GH-16937)
Test by Daniel Hillier.
(cherry picked from commit 5c32af7522d908e8c7da0243af37618433289cc5)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py
index 76e2f64..e9ef89d 100644
--- a/Lib/test/test_zipfile.py
+++ b/Lib/test/test_zipfile.py
@@ -1907,6 +1907,44 @@
self.assertRaises(TypeError, self.zip.open, "test.txt", pwd="python")
self.assertRaises(TypeError, self.zip.extract, "test.txt", pwd="python")
+ def test_seek_tell(self):
+ self.zip.setpassword(b"python")
+ txt = self.plain
+ test_word = b'encryption'
+ bloc = txt.find(test_word)
+ bloc_len = len(test_word)
+ with self.zip.open("test.txt", "r") as fp:
+ fp.seek(bloc, os.SEEK_SET)
+ self.assertEqual(fp.tell(), bloc)
+ fp.seek(-bloc, os.SEEK_CUR)
+ self.assertEqual(fp.tell(), 0)
+ fp.seek(bloc, os.SEEK_CUR)
+ self.assertEqual(fp.tell(), bloc)
+ self.assertEqual(fp.read(bloc_len), txt[bloc:bloc+bloc_len])
+
+ # Make sure that the second read after seeking back beyond
+ # _readbuffer returns the same content (ie. rewind to the start of
+ # the file to read forward to the required position).
+ old_read_size = fp.MIN_READ_SIZE
+ fp.MIN_READ_SIZE = 1
+ fp._readbuffer = b''
+ fp._offset = 0
+ fp.seek(0, os.SEEK_SET)
+ self.assertEqual(fp.tell(), 0)
+ fp.seek(bloc, os.SEEK_CUR)
+ self.assertEqual(fp.read(bloc_len), txt[bloc:bloc+bloc_len])
+ fp.MIN_READ_SIZE = old_read_size
+
+ fp.seek(0, os.SEEK_END)
+ self.assertEqual(fp.tell(), len(txt))
+ fp.seek(0, os.SEEK_SET)
+ self.assertEqual(fp.tell(), 0)
+
+ # Read the file completely to definitely call any eof integrity
+ # checks (crc) and make sure they still pass.
+ fp.read()
+
+
class AbstractTestsWithRandomBinaryFiles:
@classmethod
def setUpClass(cls):