From c274f7db7f26330385c4f671ac7e9bee8c982525 Mon Sep 17 00:00:00 2001 From: Julien Palard Date: Thu, 9 Jul 2020 11:25:19 +0200 Subject: [PATCH 1/3] tarfile: Restore fix from 011525ee92eb1c13ad1a62d28725a840e28f8160 --- Lib/tarfile.py | 2 ++ Lib/test/test_tarfile.py | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Lib/tarfile.py b/Lib/tarfile.py index e2b60532f693d4..7311fa1613c61e 100755 --- a/Lib/tarfile.py +++ b/Lib/tarfile.py @@ -2232,6 +2232,8 @@ def makelink(self, tarinfo, targetpath): try: # For systems that support symbolic and hard links. if tarinfo.issym(): + if os.path.lexists(targetpath): + os.unlink(targetpath) os.symlink(tarinfo.linkname, targetpath) else: # See extract(). diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py index d60d35b5be04ae..c22f4d578667ce 100644 --- a/Lib/test/test_tarfile.py +++ b/Lib/test/test_tarfile.py @@ -1339,10 +1339,10 @@ def test_extractall_symlinks(self): f.write('something\n') os.symlink(source_file, target_file) with tarfile.open(temparchive, 'w') as tar: - tar.add(source_file) - tar.add(target_file) + tar.add(source_file, arcname="source") + tar.add(target_file, arcname="symlink") # Let's extract it to the location which contains the symlink - with tarfile.open(temparchive) as tar: + with tarfile.open(temparchive, errorlevel=2) as tar: # this should not raise OSError: [Errno 17] File exists try: tar.extractall(path=tempdir) From ba22806c281e10bbea25e9bcce77d637e65107bb Mon Sep 17 00:00:00 2001 From: Julien Palard Date: Thu, 9 Jul 2020 11:32:39 +0200 Subject: [PATCH 2/3] news entry --- .../next/Library/2020-07-09-11-32-28.bpo-12800.fNgWwx.rst | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2020-07-09-11-32-28.bpo-12800.fNgWwx.rst diff --git a/Misc/NEWS.d/next/Library/2020-07-09-11-32-28.bpo-12800.fNgWwx.rst b/Misc/NEWS.d/next/Library/2020-07-09-11-32-28.bpo-12800.fNgWwx.rst new file mode 100644 index 00000000000000..fdd7c5e74f33a3 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-07-09-11-32-28.bpo-12800.fNgWwx.rst @@ -0,0 +1,4 @@ +Extracting a symlink from a tarball should succeed and overwrite the symlink +if it already exists. The fix is to remove the existing file or symlink +before extraction. Based on patch by Chris AtLee, Jeffrey Kintscher, and +Senthil Kumaran. From a65091510672e14e9db44705b9f04fb1ed41b28a Mon Sep 17 00:00:00 2001 From: Julien Palard Date: Tue, 24 Nov 2020 23:00:44 +0100 Subject: [PATCH 3/3] Add comment. --- Lib/tarfile.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/tarfile.py b/Lib/tarfile.py index 7311fa1613c61e..baf88323dfeafc 100755 --- a/Lib/tarfile.py +++ b/Lib/tarfile.py @@ -2233,6 +2233,7 @@ def makelink(self, tarinfo, targetpath): # For systems that support symbolic and hard links. if tarinfo.issym(): if os.path.lexists(targetpath): + # Avoid FileExistsError on following os.symlink. os.unlink(targetpath) os.symlink(tarinfo.linkname, targetpath) else: