From cfa3daa7fe9136263642ea2c334e8783d16e2ca3 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Thu, 21 May 2026 21:38:54 +0200 Subject: [PATCH] [3.13] gh-107398: Fix tarfile stream mode exception when process the file with the gzip extra field (GH-126304) (GH-150201) (cherry picked from commit 65f99329edf5d0df3ee14d9a242e1a4c8b842211) Co-authored-by: Nadeshiko Manju Co-authored-by: Serhiy Storchaka --- Lib/tarfile.py | 2 +- Lib/test/test_tarfile.py | 33 +++++++++++++++++-- ...-11-02-02-02-31.gh-issue-107398.uUtA6Q.rst | 1 + 3 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-11-02-02-02-31.gh-issue-107398.uUtA6Q.rst diff --git a/Lib/tarfile.py b/Lib/tarfile.py index cac86448842f..36cea5157ec1 100755 --- a/Lib/tarfile.py +++ b/Lib/tarfile.py @@ -489,7 +489,7 @@ class _Stream: if flag & 4: xlen = ord(self.__read(1)) + 256 * ord(self.__read(1)) - self.read(xlen) + self.__read(xlen) if flag & 8: while True: s = self.__read(1) diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py index b8b0472203e6..e8b1eb8bc033 100644 --- a/Lib/test/test_tarfile.py +++ b/Lib/test/test_tarfile.py @@ -884,10 +884,39 @@ class MiscReadTestBase(CommonReadTest): self._assert_on_file_content(hardlink_filepath, sha256_regtype) +class GzipReadTestBase: + + def test_read_with_extra_field(self): + with open(self.tarname, 'rb') as f: + data = bytearray(f.read()) + flags = data[3] + self.assertEqual(flags, 8) + data[3] = flags | 4 + data[10:10] = b'\x05\x00extra' + with open(tmpname, 'wb') as f: + f.write(data) + print(self.mode) + with tarfile.open(tmpname, mode=self.mode): + pass + + def test_read_with_file_comment(self): + with open(self.tarname, 'rb') as f: + data = bytearray(f.read()) + flags = data[3] + self.assertEqual(flags, 8) + data[3] = flags | 16 + i = data.index(0, 10) + 1 + data[i:i] = b'comment\x00' + with open(tmpname, 'wb') as f: + f.write(data) + with tarfile.open(tmpname, mode=self.mode): + pass + + class MiscReadTest(MiscReadTestBase, unittest.TestCase): test_fail_comp = None -class GzipMiscReadTest(GzipTest, MiscReadTestBase, unittest.TestCase): +class GzipMiscReadTest(GzipTest, GzipReadTestBase, MiscReadTestBase, unittest.TestCase): pass class Bz2MiscReadTest(Bz2Test, MiscReadTestBase, unittest.TestCase): @@ -959,7 +988,7 @@ class StreamReadTest(CommonReadTest, unittest.TestCase): finally: tar1.close() -class GzipStreamReadTest(GzipTest, StreamReadTest): +class GzipStreamReadTest(GzipTest, GzipReadTestBase, StreamReadTest): pass class Bz2StreamReadTest(Bz2Test, StreamReadTest): diff --git a/Misc/NEWS.d/next/Library/2024-11-02-02-02-31.gh-issue-107398.uUtA6Q.rst b/Misc/NEWS.d/next/Library/2024-11-02-02-02-31.gh-issue-107398.uUtA6Q.rst new file mode 100644 index 000000000000..d5af322d68d3 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-11-02-02-02-31.gh-issue-107398.uUtA6Q.rst @@ -0,0 +1 @@ +Fix :mod:`tarfile` stream mode exception when process the file with the gzip extra field. -- 2.47.3