diff --git a/Lib/tarfile.py b/Lib/tarfile.py index d686435d90ad1b..b733195c9c5636 100755 --- a/Lib/tarfile.py +++ b/Lib/tarfile.py @@ -601,12 +601,12 @@ class _FileInFile(object): object. """ - def __init__(self, fileobj, offset, size, blockinfo=None): + def __init__(self, fileobj, offset, size, name, blockinfo=None): self.fileobj = fileobj self.offset = offset self.size = size self.position = 0 - self.name = getattr(fileobj, "name", None) + self.name = name self.closed = False if blockinfo is None: @@ -703,7 +703,7 @@ class ExFileObject(io.BufferedReader): def __init__(self, tarfile, tarinfo): fileobj = _FileInFile(tarfile.fileobj, tarinfo.offset_data, - tarinfo.size, tarinfo.sparse) + tarinfo.size, tarinfo.name, tarinfo.sparse) super().__init__(fileobj) #class ExFileObject diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py index 75b60e9a50e78a..39f6f499c818ef 100644 --- a/Lib/test/test_tarfile.py +++ b/Lib/test/test_tarfile.py @@ -479,6 +479,13 @@ def test_length_zero_header(self): with tarfile.open(support.findfile('recursion.tar')) as tar: pass + def test_extractfile_name(self): + # gh-74468: TarFile.name must name a file, not a parent archive. + file = self.tar.getmember('ustar/regtype') + with self.tar.extractfile(file) as fobj: + self.assertEqual(fobj.name, 'ustar/regtype') + + class MiscReadTestBase(CommonReadTest): def requires_name_attribute(self): pass diff --git a/Misc/NEWS.d/next/Library/2023-03-04-20-58-29.gh-issue-74468.Ac5Ew_.rst b/Misc/NEWS.d/next/Library/2023-03-04-20-58-29.gh-issue-74468.Ac5Ew_.rst new file mode 100644 index 00000000000000..8fad551f3a4ece --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-03-04-20-58-29.gh-issue-74468.Ac5Ew_.rst @@ -0,0 +1,3 @@ +Attribute name of the extracted :mod:`tarfile` file object now holds +filename of itself rather than of the archive it is contained in. +Patch by Oleg Iarygin.