This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author andrew.garner
Recipients BreamoreBoy, adunand, andrew.garner, lars.gustaebel, serhiy.storchaka
Date 2014-07-16.04:53:35
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1405486416.32.0.338272008709.issue12800@psf.upfronthosting.co.za>
In-reply-to
Content
This seems to be a similar to issue10761 where symlinks are not being overwritten by TarFile.extract but is only an issue in streaming mode and only in python3. To reproduce, attempt to extract a symlink from a tarfile opened with 'r|' and overwrite an existing file.

Here's a simple scripts that demonstrates this behavior adapted from Aurélien's. 

#!/usr/bin/python

import os
import shutil
import sys
import tempfile
import tarfile


def main():
    tmpdir = tempfile.mkdtemp()
    try:
        os.chdir(tmpdir)
        source = 'source'
        link = 'link'
        temparchive = 'issue12800'
        # create source
        with open(source, 'wb'):
            pass
        os.symlink(source, link)
        with tarfile.open(temparchive, 'w') as tar:
            tar.add(source, arcname=os.path.basename(source))
            tar.add(link, arcname=os.path.basename(link))

        with open(temparchive, 'rb') as fileobj:
            with tarfile.open(fileobj=fileobj, mode='r|') as tar:
                tar.extractall(path=tmpdir)
    finally:
        shutil.rmtree(tmpdir)

if __name__ == '__main__':
    sys.exit(main())


On python 3.3.2 I get the following results:

$ python3.3 issue12800.py
Traceback (most recent call last):
  File "issue12800.py", line 32, in <module>
    sys.exit(main())
  File "issue12800.py", line 27, in main
    tar.extractall(path=tmpdir)
  File "/usr/lib64/python3.3/tarfile.py", line 1984, in extractall
    self.extract(tarinfo, path, set_attrs=not tarinfo.isdir())
  File "/usr/lib64/python3.3/tarfile.py", line 2023, in extract
    set_attrs=set_attrs)
  File "/usr/lib64/python3.3/tarfile.py", line 2100, in _extract_member
    self.makelink(tarinfo, targetpath)
  File "/usr/lib64/python3.3/tarfile.py", line 2181, in makelink
    os.symlink(tarinfo.linkname, targetpath)
FileExistsError: [Errno 17] File exists: '/tmp/tmpt0u1pn/link'

On python 3.4.1 I get the following results:

$ python3.4 issue12800.py
Traceback (most recent call last):
  File "/usr/lib64/python3.4/tarfile.py", line 2176, in makelink
    os.symlink(tarinfo.linkname, targetpath)
FileExistsError: [Errno 17] File exists: 'source' -> '/tmp/tmp3b96k5f0/link'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "issue12800.py", line 32, in <module>
    sys.exit(main())
  File "issue12800.py", line 27, in main
    tar.extractall(path=tmpdir)
  File "/usr/lib64/python3.4/tarfile.py", line 1979, in extractall
    self.extract(tarinfo, path, set_attrs=not tarinfo.isdir())
  File "/usr/lib64/python3.4/tarfile.py", line 2018, in extract
    set_attrs=set_attrs)
  File "/usr/lib64/python3.4/tarfile.py", line 2095, in _extract_member
    self.makelink(tarinfo, targetpath)
  File "/usr/lib64/python3.4/tarfile.py", line 2187, in makelink
    targetpath)
  File "/usr/lib64/python3.4/tarfile.py", line 2087, in _extract_member
    self.makefile(tarinfo, targetpath)
  File "/usr/lib64/python3.4/tarfile.py", line 2126, in makefile
    source.seek(tarinfo.offset_data)
  File "/usr/lib64/python3.4/tarfile.py", line 518, in seek
    raise StreamError("seeking backwards is not allowed")
tarfile.StreamError: seeking backwards is not allowed
History
Date User Action Args
2014-07-16 04:53:36andrew.garnersetrecipients: + andrew.garner, lars.gustaebel, BreamoreBoy, adunand, serhiy.storchaka
2014-07-16 04:53:36andrew.garnersetmessageid: <1405486416.32.0.338272008709.issue12800@psf.upfronthosting.co.za>
2014-07-16 04:53:36andrew.garnerlinkissue12800 messages
2014-07-16 04:53:35andrew.garnercreate