8000 gh-116931: Add fileobj parameter check for Tarfile.addfile by lyc8503 · Pull Request #117988 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

gh-116931: Add fileobj parameter check f 8000 or Tarfile.addfile #117988

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 19, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Add fileobj parameter check for Tarfile.addfile
Added additional checks for the addfile method in Tarfile.
It now throws an ValueError when the user passes in a non-zero size tarinfo but does not provide a fileobj,
instead of writing an incomplete entry.
  • Loading branch information
lyc8503 committed Apr 17, 2024
commit 0a5b2f56e3bbee4e70d195c0141eb266dc5359da
6 changes: 3 additions & 3 deletions Doc/library/tarfile.rst
Original file line number Diff line number Diff line change
Expand Up @@ -637,9 +637,9 @@ be finalized; only the internally used file object will be closed. See the

.. method:: TarFile.addfile(tarinfo, fileobj=None)

Add the :class:`TarInfo` object *tarinfo* to the archive. If *fileobj* is given,
it should be a :term:`binary file`, and
``tarinfo.size`` bytes are read from it and added to the archive. You can
Add the :class:`TarInfo` object *tarinfo* to the archive. If *tarinfo* represents
a non zero-size regular file, the *fileobj* argument should be a :term:`binary file`,
and ``tarinfo.size`` bytes are read from it and added to the archive. You can
create :class:`TarInfo` objects directly, or by using :meth:`gettarinfo`.


Expand Down
11 changes: 7 additions & 4 deletions Lib/tarfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -2214,13 +2214,16 @@ def add(self, name, arcname=None, recursive=True, *, filter=None):
self.addfile(tarinfo)

def addfile(self, tarinfo, fileobj=None):
"""Add the TarInfo object `tarinfo' to the archive. If `fileobj' is
given, it should be a binary file, and tarinfo.size bytes are read
from it and added to the archive. You can create TarInfo objects
directly, or by using gettarinfo().
"""Add the TarInfo object `tarinfo' to the archive. If `tarinfo' represents
a non zero-size regular file, the `fileobj' argument should be a binary file,
and tarinfo.size bytes are read from it and added to the archive.
You can create TarInfo objects directly, or by using gettarinfo().
"""
self._check("awx")

if fileobj is None and tarinfo.isreg() and tarinfo.size != 0:
raise ValueError("fileobj not provided for non zero-size regular file")

tarinfo = copy.copy(tarinfo)

buf = tarinfo.tobuf(self.format, self.encoding, self.errors)
Expand Down
12 changes: 10 additions & 2 deletions Lib/test/test_tarfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -1612,6 +1612,12 @@ def write(self, data):
pax_headers={'non': 'empty'})
self.assertFalse(f.closed)

def test_missing_fileobj(self):
with tarfile.open(tmpname, self.mode) as tar:
tarinfo = tar.gettarinfo(tarname)
with self.assertRaises(ValueError):
tar.addfile(tarinfo)


class GzipWriteTest(GzipTest, WriteTest):
pass
Expand Down Expand Up @@ -3283,7 +3289,8 @@ def test_add(self):
tar = tarfile.open(fileobj=bio, mode='w', format=tarformat)
tarinfo = tar.gettarinfo(tarname)
try:
tar.addfile(tarinfo)
with open(tarname, 'rb') as f:
tar.addfile(tarinfo, f)
except Exception:
if tarformat == tarfile.USTAR_FORMAT:
# In the old, limited format, adding might fail for
Expand All @@ -3298,7 +3305,8 @@ def test_add(self):
replaced = tarinfo.replace(**{attr_name: None})
with self.assertRaisesRegex(ValueError,
f"{attr_name}"):
tar.addfile(replaced)
with open(tarname, 'rb') as f:
tar.addfile(replaced, f)

def test_list(self):
# Change some metadata to None, then compare list() output
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add parameter *fileobj* check for :func:`tarfile.addfile()`
0